控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的权限交给容器,通过容器来实现对象组件的装配和管理。
Spring IOC 负责创建对象,管理对象(通过依赖注(DI),装配对象,配置对象,并且管理这些对象的整个命周期。
管理对象的创建和依赖关系的维护。对象的创建并不是⼀件简单的事,在对象关系⽐较复杂时,如果依赖关系需要程序猿来维护的话,那是相当头疼的
解耦,由容器去维护具体的对象
托管了类的产过程,如我们需要在类的产过程中做些处理,最直接的例子就是代理,如果有容器程序可以把这部分处理交给容器,应用程序则无需去关心类是如何完成代理的。
IOC 或 依赖注把应用的代码量降到最低。
它使应用容易测试,单元测试不再需要单例和JNDI查找机制。
最小的代价和最小的侵性使松散耦合得以实现。
IOC容器支持加载服务时的饿汉式初始化和懒加载。
Spring 中的 IoC 的实现原理就是工厂模式加反射机制。
依赖注入,即组件之间的依赖关系由容器在应用系统运行期来决定,由容器动态地将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中。注入方式有:构造器、属性、setter方法。
不是,Spring框架中的单例 bean 不是线程安全的。
spring 中的 bean 默认是单例模式,spring 框架并没有对单例 bean 进行多线程的封装处理。
spring 通过 ThreadLocal 对一些 bean 进行了非线程安全处理,解决线程安全问题。例如:HttpServletRequest
,所以在 Controller 中注入 HttpServletRequest
是线程安全的。
ThreadLocal 会为每个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每个线程都拥有自己的变量副本,从也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。
spring 生命周期中的阶段,包括:初始化、使用、销毁。
@Autowired 和 @Resource 之间的区别?
注解内部定义的参数不同:
@Autowired 内部只有一个参数 required
,默认值为 true
@Resource 内部有多个参数,比较重要的有 name
和 type
。
默认注入方式不同:
@Autowired 默认是按照类型装配注入的,默认情况下它要求依赖对象必须存在(可以设置它required属性为false)。
@Resource 默认是按照名称来装配注入的,只有当找不到与名称匹配的 bean 才会按照类型来装配注入。
注解应用范围不同:
@Autowired 可用用在构造方法、方法、方法参数、成员变量、注解上。
@Resource 可用用在 类、方法、成员变量。
出处不同:
@Autowired 是 spring 定义的注解。
@Resource 是由 jdk 提供的,它遵循 JSR-250 这个规范。
所以 @Autowired 只适用于 spring 框架,而 @Resource 适用于所有的 Java 框架 。
Spring AOP中的动态代理主要有两种式,JDK 动态代理和 CGLIB 动态代理:
JDK动态代理只提供接口的代理,不支持类的代理。核心 InvocationHandler
接口和Proxy类,InvocationHandler
通过invoke()
方法反射来调用目标标类中的代码,动态地将横切逻辑和业务编织在一起;接着,Proxy
利用 InvocationHandler
动态创建一个符合某一接口的的实例, 生成目标类的代理对象。
如果代理类没有实现 InvocationHandler
接口,那么 Spring AOP 会选择使 CGLIB 来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成成指定类的一个类的子对象,并覆盖其中特定方法并添加增强代码,从而实现AOP。CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为 final,那么它是无法法使用 CGLIB做动态代理的。
BeanFactory 保存了所有需要对外提供的 Bean 的实例。相当于 IoC 容器的顶级接口,是 IoC 容器最基础的实现。提供访问 spring 容器的根接口。主要负责 bean 的创建和访问。其中最主要的一个方法是 getBean() 方法。完成对 Bean 的依赖注入的功能。
FactoryBean 是一个特殊的 Bean,它可以返回创建 bean 的工厂,如果配置不同的类,可以返回不同类型的 bean,它有一个比较核心的方法叫做 getObject()。可以在 beanName 前面加上 & 符号获取 bean 对应的 Factory。同时可以通过自定义 FactoryBean来扩展创建 Bean的规则。