ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Java面试——Spring原理及应用(一)

Java面试——Spring原理及应用(一) Spring原理及应用1、Spring的特性1.1、轻量1.2、控制反转1.3、面向容器1.4、面向切面1.5、框架灵活2、Spring的模块2.1、核心容器层2.1.1、Spring-Beans2.1.2、Spring-Core2.1.3、Spring-Context2.1.4、SpEL2.2、数据访问层2.2.1、JDBC2.2.2、ORM2.2.3、OXM2.2.4、JMS2.2.5、事务处理2.3、Web应用层2.3.1、Web2.3.2、Web-MVC2.3.3、Web-Socket2.3.4、Web-Portlet2.4、其他重要模块2.4.1、AOP2.4.2、Aspects2.4.3、Instrumentation2.4.4、Messaging2.4.5、Test3、Spring的核心JAR包4、Spring的注解4.1、Spring注解的使用4.1.1、导入命名空间及规范4.1.2、配置扫描包4.1.3、使用注解4.2、Spring的常用注解5、Spring IoC的原理5.1、Spring IoC简介5.2、Spring Bean的装配流程5.3、Spring Bean的作用域5.3.1、Singleton5.3.2、Prototype5.3.3、Request5.3.4、Session5.3.5、Global Session5.4、Spring Bean的生命周期5.5、Spring的4种依赖注入5.5.1、构造器注入5.5.2、set方法注入5.5.3、静态工厂注入5.5.4、实例工厂注入5.6、自动装配的5种方式1、Spring的特性Spring基于J2EE技术实现了一套轻量级的Java WebService系统应用框架。它有很多优秀的特性很多公司都选择把Spring作为产品或项目的基础开发架构。Spring的特性包括轻量、控制反转Inversion of ControlIoC​、面向容器、面向切面Aspect OrientedProgrammingAOP和框架灵活具体如图所示。1.1、轻量从JAR包的大小上来说Spring是一个轻量级的框架其核心JAR包spring-web-5.2.0.RELEASE.jar和spring-core-5.2.0.RELEASE.jar的大小均为1.4MB左右从系统的资源使用上来说Spring也是一个轻量级的框架其运行期间只需要少量的操作系统资源内存和CPU便能稳定运行。除此之外Spring还是模块化的应用程序在使用过程中可以根据需求引入模块以JAR包依赖方式引入来实现不同的功能使其应用更加灵活。1.2、控制反转Spring的控制反转指一个对象依赖的其他对象将会在容器的初始化完成后主动将其依赖的对象传递给它而不需要这个对象自己创建或者查找其依赖的对象。Spring基于控制反转技术实现系统对象之间依赖的解耦。1.3、面向容器Spring实现了对象的配置化生成和对象的生命周期管理因此可以理解为其是面向容器的。通过Spring的XML文件或者注解方式应用程序可以配置每个Bean对象被创建和销毁的时间以及Bean对象创建的先后顺序和依赖关系。Spring中的实例对象可以是全局唯一的单例模式也可以在每次需要时都重新生成一个新的实例具体以哪种方式创建Bean对象由Bean的生命周期决定通过prototype属性来定义。1.4、面向切面Spring提供了面向切面的编程支持面向切面技术通过分离系统逻辑和业务逻辑来提高系统的内聚性。在具体的使用过程中业务层只需要关注并实现和业务相关的代码逻辑而不需要关注系统功能例如系统日志、事务支持和业务功能的复杂关系Spring通过面向切面技术将系统功能自动织入业务逻辑的关键点。1.5、框架灵活基于容器化的对象管理技术Spring中的对象可以被声明式地创建例如通过XML文件或注解的方式定义对象和对象之间的依赖关系。Spring作为一个轻量级的J2EE Web框架具有事务管理、持久化框架集成和Java Web服务等功能应用程序可以根据需求引入相应的模块以实现不同的功能。2、Spring的模块Spring为企业应用程序提供一站式服务。Spring是模块化的允许应用按需引入各个模块。Spring提供的常用模块有核心容器层Core Container​、数据访问层DataAccess​、Web应用层Web Access​。除此之外Spring还包括AOP、Aspects、Instrumentation、Messaging和Test。Spring的模块如图所示。下面对Spring中各个核心的模块做简单的介绍。2.1、核心容器层核心容器层由Spring-Beans、Spring-Core、Spring-Context和SpELSpring Expression LanguageSpring表达式语言等模块组成。2.1.1、Spring-BeansSpring-Beans模块基于工厂模式实现对象的创建。Spring-Beans通过XML配置文件实现了声明式的对象管理将对象之间复杂的依赖关系从实际编码逻辑中解耦出来。2.1.2、Spring-CoreSpring-Core模块是Spring的核心功能实现具体包括控制反转和依赖注入。所谓依赖注入是指在一个Bean实例中引用另外一个Bean实例时Spring容器会自动创建其所依赖的Bean实例并将该Bean实例注入传递到对应的Bean中。2.1.3、Spring-ContextSpring-Context模块是在Spring-Beans和Spring-Core模块的基础上构建起来的。Spring-Context模块继承自Spring-Beans模块并且添加了国际化、事件传播、资源加载和透明地创建上下文等功能。同时Spring-Context模块提供了一些J2EE的功能比如EJB、JMX和远程调用等。ApplicationContext接口是Spring-Context模块操作Bean的入口。Spring-Context-Support提供了将第三方库集成到Spring-Context的支持比如缓存EhCache、Guava、JCache​、邮件JavaMail​、调度CommonJ、Quartz和模板引擎FreeMarker、JasperReports、Velocity等。2.1.4、SpELSpEL模块提供了丰富的表达式语言支持用于在运行过程中查询和操作对象实例。SpEL在JSP 2.1表达式语言规范的基础上进行了扩展支持set方法、get方法、属性赋值、方法调用、访问数组集合、索引内容、逻辑算术运算、命名变量、基于名称在Spring IoC容器检索对象同时支持列表的投影、选择和聚合等功能。2.2、数据访问层数据访问层包括JDBC、ORM、OXM、JMS和事务处理模块。它们的术语描述如下表所示。2.2.1、JDBCJDBC模块提供了JDBC抽象层。Spring持久化层基于JDBC抽象层实现了在不同数据库之间灵活切换而不用担心不同数据库之间SQL语法的不兼容。2.2.2、ORMORM模块提供了对象关系映射API的集成包括JPAJava Persistence API​、JDOJava Data Object和Hibernate等。基于该模块ORM框架能很容易地和Spring的其他功能例如事务管理整合。2.2.3、OXMOXM模块提供了对OXM实现的支持比如JAXB、Castor、XML Beans、JiBX、XStream等。2.2.4、JMSJMS模块包含消息的生产Produce和消费Consume功能。从Spring 4.1开始Spring集成了Spring-Messaging模块用于实现对消息队列的支持。2.2.5、事务处理事务处理Transactions模块基于接口方式实现了声明式事务管理。编程式事务的实现需要应用程序调用相应的beginTransaction​​、commit​​、rollback​等方法来实现事务的管理Spring声明式事务只需要通过注解或配置即可实现事务的管理具体的事务管理工作由Spring自动处理应用程序不需要关心事务的提交Commit和回滚Rollback​。2.3、Web应用层Web应用层主要包含Web交互和数据传输等相关功能由Web、Web-MVC、Web-Socket、Web-Portlet组成。2.3.1、WebWeb模块不但提供了面向Web应用的基本功能还提供了HTTPHyper Text Transfer Protocol超文本传输协议客户端及Spring远程调用中与Web相关的部分。Web模块基于Servlet监听器初始化IoC容器。2.3.2、Web-MVCWeb-MVC模块为Web应用提供了模型视图控制ModelView ControllerMVC和REST API服务的实现。Spring的MVC框架使数据模型和视图分离数据模型负责数据的业务逻辑视图负责数据的展示。同时Web-MVC可与Spring框架的其他模块方便地集成。2.3.3、Web-SocketWeb-Socket模块提供了对WebSocket-Base的支持用于实现在Web应用程序中服务端和客户端实时双向通信尤其在实时消息推送中应用广泛。2.3.4、Web-PortletWeb-Portlet模块提供了基于Portlet环境的MVC实现并提供了与Spring Web-MVC模块相关的功能。2.4、其他重要模块除了上述介绍的模块Spring还有其他一些重要的模块例如AOP、Aspects、Instrumentation、Messaging和Test等。2.4.1、AOPAOP模块提供了面向切面的编程实现允许应用程序通过定义方法拦截器和切入点来实现系统功能和业务功能之间的解耦。2.4.2、AspectsAspects模块提供了Spring与AspectJ的集成是一个面向切面编程的模块。2.4.3、InstrumentationInstrumentation模块在应用中提供了对Instrumentation的支持和类加载器的实现。2.4.4、MessagingMessaging模块为STOMPSimple Text OrientatedMessaging Protocol简单文本定向消息协议提供了支 持主要用于应用程序中WebSocket子协议的实现。同时Messaging模块可通过注解的方式来选择和处理来自WebSocket客户端的STOMP消息。2.4.5、TestTest测试模块用于对JUnit或TestNG等测试框架提供支持以实现Spring代码的自动化测试。3、Spring的核心JAR包Spring基于模块化实现每个模块都对应不同的JAR包。要全面了解Spring首先应从JAR包开始但是SpringJAR包众多每个包中又都含有复杂的技术原理鉴于篇幅原因下表对常用的JAR包和功能做了简单介绍以便读者能够整体了解Spring的核心技术架构。4、Spring的注解Spring的注解将应用程序中Bean的定义和Bean之间复杂的依赖关系的配置从XML配置中解放出来应用程序只需在需要某些服务或者功能时使用注解依赖注入即可具体Bean的定义和依赖关系由Spring的自动装配来完成。这使得Spring的使用更加方便。4.1、Spring注解的使用Spring注解的使用很简单首先导入命名规范然后指定IoC的扫描包最后在Java类中直接使用注解依赖注入需要的资源即可。4.1.1、导入命名空间及规范在Spring的applicationContext.xml配置文件中导入命名空间及规范。代码如下。4.1.2、配置扫描包在applicationContext.xml配置文件中配置需要扫描的包。如下代码开启了自动扫描com.alex.spring包下的所有类也就是说只有在com.alex.spring包中的注解才能够生效。完整的Spring注解配置文件如下。4.1.3、使用注解使用注解比较简单直接在Java类中用按需使用即可。具体代码如下。4.2、Spring的常用注解Spring的注解在开发中无处不在常用注解如表所示。5、Spring IoC的原理5.1、Spring IoC简介Spring通过一个配置文件描述Bean和Bean之间的依赖关系利用Java的反射功能实例化Bean并建立Bean之间的依赖关系。Spring的IoC容器在完成这些底层工作的基础上还提供了Bean实例缓存管理、Bean生命周期管理、Bean实例代理、事件发布和资源装载等高级服务。5.2、Spring Bean的装配流程Spring在启动时会从XML配置文件或注解中读取应用程序提供的Bean配置信息并在Spring容器中生成一份相应的Bean配置注册表然后根据这张注册表实例化Bean装配好Bean之间的依赖关系为上层业务提供基础的运行环境。其中Bean缓存池为HashMap实现。SpringBean的装配流程如图所示。5.3、Spring Bean的作用域Spring为Bean定义了5种作用域分别为Singleton单例​、Prototype原型​、Request请求级别​、Session会话级别和Global Session全局会话​。5.3.1、SingletonSingleton是单例模式当实例类型为单例模式时Spring IoC容器中只会存在一个共享的Bean实例无论有多少个Bean引用它都始终指向同一个Bean对象。该模式在多线程下是不安全的。Singleton作用域是Spring中的默认作用域也可以通过配置将Bean定义为Singleton模式具体配置如下。5.3.2、PrototypePrototype是原型模式每次通过Spring容器获取Prototype定义的Bean时容器都将创建一个新的Bean实例每个Bean实例都有自己的属性和状态而Singleton全局只有一个对象。因此对有状态的Bean经常使用Prototype作用域而对无状态的Bean则使用Singleton作用域。具体配置如下。5.3.3、RequestRequest指在一次HTTP请求中容器会返回该Bean的同一个实例而对不同的HTTP请求则会创建新的Bean实例并且该Bean实例仅在当前HTTP请求内有效当前HTTP请求结束后该Bean实例也将会随之被销毁。具体配置如下。5.3.4、SessionSession指在一次HTTP Session中容器会返回该Bean的同一个实例而对不同的Session请求则会创建新的Bean实例该Bean实例仅在当前Session内有效。和HTTP请求相同每一次Session都会创建新的Bean实例而不同的Bean实例之间不共享数据且Bean实例仅在自己的Session内有效请求结束则Bean实例将随之被销毁。具体配置如下。5.3.5、Global SessionGlobal Session指在一个全局的HTTP Session中容器会返回该Bean的同一个实例且仅在使用Portlet Context时有效。5.4、Spring Bean的生命周期Spring Bean的生命周期执行过程如图所示。实例化一个Bean。按照Spring上下文对实例化的Bean进行配置。如果这个Bean实现了BeanNameAware接口则会调用它实现的setBeanNameString方法该方法传递的参数是Spring配置文件中Bean的id值。如果这个Bean实现了BeanFactoryAware接口则会调用它实现的setBeanFactoryBeanFactory方法该方法传递的参数是Spring工厂自身。如果这个Bean实现了ApplicationContextAware接口则会调用setApplication ContextApplicationContext方法该方法传入的参数是Spring上下文。如果该Bean关联了BeanPostProcessor接口则会调用postProcessBefore InitializationObject objString s方法该方法在Bean初始化前调用常用于定义初始化Bean的前置工作比如系统缓存的初始化。如果Bean在Spring配置文件中配置了init-method属性则会自动调用其配置的初始化方法。如果某个Bean关联了BeanPostProcessor接口将会调用postProcessAfter InitializationObject objString s方法。至此Bean的初始化工作就完成了应用程序就可以开始使用Bean实例了。当Bean不再被需要时会在清理阶段被清理掉。如果Bean实现了DisposableBean接口则Spring会在退出前调用实现类的destroy​方法。如果某个Bean的Spring配置文件中配置了destroy-method属性在Bean被销毁前会自动调用其配置的销毁方法。5.5、Spring的4种依赖注入5.5.1、构造器注入构造器注入指通过在类的构造函数中注入属性或对象来实现依赖注入。如下代码通过标签配置了一个id为persionDaoImpl的Bean并通过标签在其构造函数中注入了一个message属性注入完成后在类中可以直接通过this.message获取注入的属性值。5.5.2、set方法注入set方法注入是通过在类中实现get、set方法来实现属性或对象的依赖注入的。如下代码通过标签配置了一个id为persionDaoImpl的Bean并通过标签在Bean中注入了一个id为123的属性值注入完成后在类中可以直接使用getId​获取注入的属性。5.5.3、静态工厂注入静态工厂注入是通过调用工厂类中定义的静态方法来获取需要的对象的为了让Spring管理所有对象应用程序不能直接通过“工厂类.静态方法​​”的方式获取对象而需要通过Spring注入的方式获取。代码如下。上述代码定义了一个DaoFactory工厂类和getStaticFactoryDaoImpl​静态工厂方法该方法实例化并返回一个StaticFactoryDaoImpl实例同时定义了一个SpringAction类并通过setStaticFactoryDao获取注入的FactoryDao。具体的XML注入语法如下。上述代码定义了一个name为staticFactoryDao的工厂类并通过factory-method定义了实例化对象的方法这里实例化对象的方法是一个名为getStaticFactoryDaoImpl的静态方法。该静态方法返回一个工厂类实例在springAction中通过property/property标签注入静态工厂实例。5.5.4、实例工厂注入实例工厂注入指的是获取对象实例的方法是非静态的因此首先需要实例化一个工厂类对象然后调用对象的实例化方法来实例化对象。具体代码如下。上述代码定义了一个name为factoryDao的工厂类并通过factory-method定义了实例化对象的方法这里实例化对象的方法是一个名为getFactoryDaoImpl的方法。该方法返回一个工厂类在springAction中通过property/property标签注入工厂实例。5.6、自动装配的5种方式Spring的装配方式包括手动装配和自动装配。手动装配包括基于XML装配构造方法、set方法等和基于注解装配2种方式。自动装配包括5种装配方式这5种方式均可以用来引导Spring容器自动完成依赖注入具体如下。no关闭自动装配通过显式设置ref属性来进行对象装配。byName通过参数名自动装配Bean的autowire被设置为byName后Spring容器试图匹配并装配与该Bean的属性具有相同名字的Bean。byType通过参数类型自动装配Bean的autowire被设置为byType后Spring容器试图匹配并装配与该Bean的属性具有相同类型的Bean。constructor通过设置构造器参数的方式来装配对象如果没有匹配到带参数的构造器参数类型则Spring会抛出异常。autodetect首先尝试使用constructor来自动装配如果无法完成自动装配则使用byType方式进行装配。
返回列表