1. 何为Spring?
Spring是一个轻量级的IoC(DI)和AOP容器框架,为简化企业级应用开发而生。由以下几个主要模块组成:
- Spring core:核心类库,提供IoC服务;
- Spring Context:提供框架式的Bean访问形式,以及企业级功能的开发;
- Spring AOP:提供AOP服务;
- Spring ORM:对现有的ORM框架提供支持;
- Spring DAO:对JDBC进行封装,简化数据访问;
- Spring MVC:提供面向Web应用的Model-View-Controller 实现。
2. Spring框架的优良特性
- 非侵入式:基于Spring开发的应用中的对象可以不依赖与Spring的API;
- 依赖注入:DI(Dependency Injection),反转控制(IOC)最经典的实现,将对象的依赖关系交给框架处理,减低组件的耦合性;
- 面向切面编程:提供了 AOP 技术,支持将一些通用任务,如安全.事务.日志. 权限等进行集中式管理,从而提供更好的复用;
- 容器化:Spring是一个容器,因为它包含并且管理应用对象的生命周期;
- 组件化:Spring实现了使用简单的组件配置组合成一个复杂的应用。在 Spring 中可以使用XML和Java注解组合这些对象;
- 一站式:在IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的第三方类库(实际上Spring 自身也提供了表述层的SpringMVC和持久层的Spring JDBC)。
3. 何为AOP?
AOP,一般称为面向切面,作为面向对象的一中补充,用于将那些和业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被叫做“切面”,在减少系统中重复代码,降低模块间的耦合度的同时,提高了系统的可维护性。多用于权限认证、日志、事务处理。
AOP的实现关键在于 代理模式,静态代理的代表是AspectJ;动态代理则是Spring AOP。
- AspectJ 是静态代理的增强,所谓静态代理就是AOP框架会在编译阶段生成AOP代理类,因此也被称为编译时增强,他会在编译阶段将AspectJ(切面)编入Java字节码中,运行时就是增强之后的AOP对象。
- Spring AOP 使用的是动态代理,所谓动态代理就是说AOP框架不回去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。
在Spring AOP中的动态代理有两种方式,JDK动态代理和Cglib动态代理。
- JDK 动态代理只提供接口的代理,不支持类的代理。核心 InvocationHandler 接口和Proxy类,InvocationHandler 通过
invoke()
方法反射来调用目标类中的代码,动态的将横切逻辑和业务编织在一起;接着,Proxy 利用InvocationHandler 动态创建一个符合某一接口的实例,生成目标代理对象。 - 如果代理类没有实现InvocationHandler接口,那么SpringAOP 会选择使用Cglib 进行动态代理目标类。Cglib(Cide Generation Libratry),是一个代码生成的类库,可以在运行时动态的生成指定类的一个子类对象,并覆盖其中特定方法且可以添加增强代码,从而实现AOP。Cglib 是通过继承的方法做的动态代理,以为如果某个类被标记了Final,那么它是无法使用Cglib 做动态代理的。
- 静态代理和动态代理的区别在于生成AOP 代理对象的实际不同,相对来说AspectJ 的静态代理方式具有更好的性能,但是AspectJ 需要特定的编译器进行处理,而SpringAOP 不需要特定的编译器处理。
4. 何为IoC?
IoC 控制反转,指创建对象的控制权的转移,以前创建对象的主动权和时机是由自己控制的,而现在这种权力转移到Spring 容器中,并由容器根据配置文件去创建实例和管理各个实例之间的依赖关系,对象与对象之间松散耦合,也利于功能的复用。这一思想完全颠覆了应用程序组件获取资源的传统方式:反转了资源的获取方向——改由容器主动的将资源推送给需要的组件,开发人员不需要知道容器是如何创建资源对象的,只需要提供接收资源的方式即可,极大的降低了学习成本,提高了开发的效率。这种行为也称为查找的被动形式。
DI 依赖注入,和控制反转是同一概念的不同角度的描述:应用程序在运行时依赖IoC容器来动态注入对象需要的外部资源(IoC 就是一种反转控制的思想, 而DI是对IoC的一种具体实现)。
最直观的表述就是:IoC让对象的创建不用去new了,可以由Spring 自动产生,使用Java的反射机制,根据配置文件在运行时动态的创建对象以及管理对象,并调用对象中的方法。
Spring 的IoC 有三种注入方式:构造器注入、setter 方法注入、根据注解注入
IOC 让相互协作的组件保持松散的耦合,而 AOP 编程允许你把遍布于应用各层的功能分离出来形成可重用的功能组件。
5. IOC容器如何造在Spring中的实现?
Spring中有IOC思想, IOC思想必须基于 IOC容器来完成, 而IOC容器在最底层实质上就是一个对象工厂。在通过IOC容器读取Bean的实例之前,需要先将IOC容器本身实例化。Spring提供了IOC容器的两种实现方式:
- BeanFactory:IOC容器的基本实现,是Spring内部的基础设施,是面向Spring本身的,不是提供给开发人员使用的。
- ApplicationContext:BeanFactory的子接口,提供了更多高级特性。面向Spring的使用者,几乎所有场合都使用ApplicationContext而不是底层的BeanFactory。
6. BeanFactory 和ApplicationContext 有什么区别?
BeanFactory 和 ApplicationContext 是 Spring 的两大核心接口,都可以当做 Spring 的容器。其中 ApplicationContext 是 BeanFactory 的子接口。
- BeanFactory:是 Spring 里面最底层的接口,包含了各种 Bean 的定义,读取 bean 配置文档,管理 bean 的加载.实例化,控制 bean 的生命周期, 维护 bean 之间的依赖关系。ApplicationContext 接口作为 BeanFactory 的派生,除了提供 BeanFactory 所具有的功能外,还提供了更完整的框架功能:
-
继承 MessageSource,因此支持国际化。统一的资源文件访问方式。
-
提供在监听器中注册 bean 的事件。同时加载多个配置文件。
-
载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的 web 层。
-
BeanFactroy 采用的是延迟加载形式来注入 Bean 的,即只有在使用到某个 Bean 时(调用 getBean()),才对该 Bean 进行加载实例化。这样,我们就不能发现一些存在的Spring 的配置问题。如果Bean 的某一个属性没有注入, BeanFacotry 加载后,直至第一次使用调用 getBean 方法才会抛出异常。ApplicationContext,它是在容器启动时,一次性创建了所有的 Bean。这样,在容器启动时,我们就可以发现 Spring 中存在的配置错误,这样有利于检查所依赖属性是否注入。ApplicationContext 启动后预载入所有的单实例Bean, 通过预载入单实例 bean ,确保当你需要的时候,你就不用等待,因为它们已经创建好了。相对于基本的 BeanFactory,ApplicationContext 唯一的不足是占用内存空间。当应用程序配置 Bean 较多时,程序启动较慢。
-
BeanFactory 通常以编程的方式被创建,ApplicationContext 还能以声明的方式创建,如使用 ContextLoader。
-
BeanFactory 和 ApplicationContext 都支持BeanPostProcessor.BeanFactoryPostProcessor 的使用,但两者之间的区别是:BeanFactory 需要手动注册,而 ApplicationContext 则是自动注册。
如果你想得到,你就会得到,你所需要付出的只是行动