Spring IOC原理
IOC(Inversion of Control)控制反转另外一种说法叫DI(Dependency Injection)即依赖注入。它并不是一种技术实现,而是一种设计思想。从实现原理上来讲,IOC其实就是反射变成,通过类名来动态生成对象。最主要是完成了对象创建和依赖的注入管理。
image.png
Spring IOC涉及定义
bean的xml配置文件:我们以xml形式描述bean的名称、属性等信息。
BeanDefinition:Spring将bean的注解、xml配置信息存储为Spring可以理解的结构化描述信息。
BeanFactory:即IOC容器,是Spring的核心。在这集出场扩展多种IOC容器满足不同需求,例如常用ApplicationContext。
IoC容器初始化:
image.png
依赖注入过程
image.png
IOC容器Bean
Java Bean是一个满足规范的类。
BeanFaoctory体系
BeanFactory作为最顶层的一个接口类,它定义了IOC容器的基本功能规范。
public interface BeanFactory {
/**
* 对FactoryBean的转义定义,因为如果使用bean的名字检索FactoryBean得到的对象是工厂生成的对象,如果需要得到工厂本身,需要转义
*/
String FACTORY_BEAN_PREFIX = "&";
/**
* 根据bean的名字,获取在IOC容器中得到bean实例
*/
Object getBean(String name) throws BeansException;
/**
* 根据bean的名字和Class类型来得到bean实例,增加了类型安全验证机制
*/
<T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException;
/**
* 根据bean的名字和Class类型来得到bean实例,args实例化bean时的参数
*/
Object getBean(String name, Object... args) throws BeansException;
/**
* 根据bean的Class类型类获取bean实例
*/
<T> T getBean(Class<T> requiredType) throws BeansException;
/**
* 根据bean的Class类型类获取bean实例,args实例化bean时的参数
*/
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
/**
* 提供对bean的检索,看看是否在IOC容器有这个名字的bean
*/
boolean containsBean(String name);
/**
* 根据bean名字得到bean实例,并同时判断这个bean是不是单例
*/
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
/**
* [2.0.3新增]根据bean名字得到bean实例,并同时判断这个bean是不是原型
*/
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
/**
* 检查给定名称的getBean调用是否将返回可分配给指定目标类型的对象。
*/
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
/**
* [2.0.1版本新增]检查给定名称的getBean调用是否将返回可分配给指定目标类型的对象。
*/
boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
/**
* 得到bean实例的Class类型
*/
@Nullable
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
/**
* 得到bean的别名,如果根据别名检索,那么其原名也会被检索出来
*/
String[] getAliases(String name);
}
BeanFactory初始化顺序如下:
1、BeanNameAware的setBeanName;
2、BeanClassLoaderAware的setBeanClassLoader;
3、BeanFactoryAware的setBeanFactory;
4、EnvironmentAware的setEnvironment;
5、EmbeddedValueResolverAware的setEmbeddedValueResolver;
6、ResourceLoaderAware的setResourceLoader(仅适用与运行时的应用上下文) ;
7、ApplicationEventPublisherAware的setApplicationEventPublisher (仅适用与运行时的应用上下文) ;
8、MessageSourceAware的setMessageSource (仅适用与运行时的应用上下文) ;
9、ApplicationContextAware的setApplicationContext (仅适用与运行时的应用上下文) ;
10、ServletContextAware 的setServletContext (仅适用与运行时的应用上下文) ;
11、 BeanPostProcessors的postProcessBeforeInitialization方法;
12、InitializingBean的afterPropertiesSet;
13、自定义一个初始化方法(init-method);
14、BeanPostProcessors的postProcessAfterInitialization方法;
关闭BeanFactory时,以下生命周期方法适用:
1、DestructionAwareBeanPostProcessors的postProcessBeforeDestruction方法;
2、DisposableBeans destroy ;
3、自定义一个销毁方法(destroy-method)
Bean作用域
Spring 定义了多种Bean作用域
单例(Singleton):在整个应用中只有一个实例
原型(Prototype):每次使用的时候都会创建一个新实例
会话(Session):web应用中,为每个会话保留一份实例
请求(Request):web应用中,每次请求创建一个实例
Bean生命周期
Spring对Bean进行实例化,默认是单例模式。
Spring对Bean进行依赖注入,使用反射方法。
bean已经准备就绪,驻留在应用上下文中,直到该应用上下文被销毁
Bean实例被销毁,spring将调用它的distroy()接口方法。
单例对象管理
Spring在读取xml、注解配置时,默认创建该实例。
创建对象时调用构造器和init-method方法
实例被销毁时会调用destroy-method方法
lazy-init="true",可以让这个对象在第一次被访问的时候创建
非单例对象管理
Spring在读取xml、注解配置时,不会创建实例
在每一次访问容器实例时,都会创建新对象,并调用构造方法和init-method
在对象销毁时不会调用任何方法
Bean 自动注入
spring IoC容器可以自动装配(autowire)相互协作bean之间的关联关系。
byName:通过属性的名称自动装配(注入)。Spring会在容器中查找名称与bean属性名称一致的bean,并自动注入到bean属性中。bean的属性需要有setter方法。
byType:通过类型自动装配(注入)。Spring会在容器中查找类(Class)与bean属性类一致的bean,并自动注入到bean属性中,如果容器中包含多个这个类型的bean,Spring将抛出异常。如果没有找到这个类型的bean,那么注入动作将不会执行。
constructor:类似于byType,但是是通过构造函数的参数类型来匹配。假设bean A有构造函数A(B b, C c),那么Spring会在容器中查找类型为B和C的bean通过构造函数A(B b, C c)注入到A中。与byType一样,如果存在多个bean类型为B或者C,则会抛出异常。但时与byType不同的是,如果在容器中找不到匹配的类的bean,将抛出异常,因为Spring无法调用构造函数实例化这个bean。
网友评论