1、IOC的理解
IOC也叫控制反转,是将对象的创建和管理交给spring来做。
了解spring IOC,先了解几个相关类:
(1)IOC容器-BeanFactory
BeanFactory是IOC容器的顶层接口,定义一些基础功能,ApplicationContext是IOC容器的高级接口,功能更多,如资源的访问(XML文件、Java配置类)等;他们都是负责生产和管理bean的工厂。
(2)Bean和BeanDefinition
BeanDefinition是spring对bean的定义信息,spring将XML配置文件或注解解析成BeanDefinition,然后根据BeanDefinition可以实例化为Bean。
spring的bean有两种:一种是普通bean,一种是工厂bean(FactoryBean),FactoryBean可以生成并返回某一个类型的bean实例,可以借助于它自定义Bean的创建过程,它在spring框架的一些组件中常用。
(3)后置处理器
spring提供了两种后置处理器:BeanPostProcessor和BeanFactoryPostProcessor。
-
BeanPostProcessor是针对bean级别的处理器,如果一个类实现了BeanPostProcessor,默认对spring容器中所有的bean进行处理。可以通过参数对某个bean进行处理。第一个参数是bean实例,第二个参数是bean的name。
注意:BeanPostProcessor的两个方法分别是在初始化方法(init-method)前后执行,也就是在bean实例化和依赖注入之后执行。
其实常用的@PostConstruct注解也是利用BeanPostProcessor实现的,InitDestroyAnnotationBeanPostProcessor 后置处理器的 postProcessBeforeInitialization() 方法会判断每个Bean是否有方法被@PostConstruct注解标注,标注了就执行。(也就是@PostConstruct也只对使用了它的bean生效)
public interface BeanPostProcessor { @Nullable default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } @Nullable default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } }
-
BeanFactoryPostProcessor是针对BeanFactory级别的处理。
@FunctionalInterface public interface BeanFactoryPostProcessor { void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException; }
此接口只提供了一个方法,方法参数为ConfigurableListableBeanFactory,根据该参数的getBeanDefinition()可以获取BeanDefinition对定义的bean属性进行修改。
注意:调用 BeanFactoryPostProcessor 方法时,这时候bean还没有实例化,此时 bean 刚被解析成 BeanDefinition对象。
(4)初始化Bean—InitializingBean
此接口只有一个方法,在初始化方法init()执行前调用
public interface InitializingBean { void afterPropertiesSet() throws Exception; }
注意:BeanPostProcessor 是对容器所有Bean都会执行,也就是只要有接口实现了BeanPostProcessor,就会作用于所有Bean;InitializingBean 不一样,它只作用于实现了该接口的Bean。
2、bean的生命周期
-
实例化:这个阶段就是Spring加载XML配置文件或扫描注解,将类解析为BeanDefinition,然后通过反射机制创建Bean对象的过程。
-
依赖注入:实例化完成之后,Spring就会调用Bean对应的setXxx()方法、或者构造方法给相应的属性赋值。
-
初始化:在Bean实例化完成并且依赖注入之后,就会调用Bean的初始化方法,进行一些额外的处理操作,默认初始化方法一般叫做【init()】。
-
使用阶段:处于这个阶段的Bean对象,就可以真正的被使用啦。
-
销毁阶段:当某个Bean对象不再被使用时候,此时会首先调用销毁方法(默认销毁方法我们习惯叫做【destory()】),用于释放一些系统资源,然后将Bean对象进行垃圾回收
3、spring源码
3.1、spring IOC容器启动主流程
spring IOC初始化的关键环节在 AbstractApplicationContext#refresh() 方法中。
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // 第1步:刷新前预处理. prepareRefresh(); // 第2步:获取BeanFactory,默认实现是DefaultListableBeanFactory;加载BeanDefition 并注册到 BeanDefitionRegistry. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 第3步:BeanFactory的预准备工作(BeanFactory进行一些设置,比如context的类加 载器等). prepareBeanFactory(beanFactory); try { // 第4步:BeanFactory准备工作完成后进行的后置处理工作. postProcessBeanFactory(beanFactory); // 第5步:实例化并调用实现了BeanFactoryPostProcessor接口的Bean. invokeBeanFactoryPostProcessors(beanFactory); // 第6步:注册BeanPostProcessor(Bean的后置处理器),在创建bean的前后等执 . registerBeanPostProcessors(beanFactory); // 第7步:初始化MessageSource组件(做国际化功能;消息绑定,消息解析). initMessageSource(); // 第8步:初始化事件派发器. initApplicationEventMulticaster(); // 第9步:子类重写这个方法,在容器刷新的时候可以自定义逻辑. onRefresh(); // 第10步:注册应用的监听器。就是注册实现了ApplicationListener接口的监听器Bean. registerListeners(); /** 第11步:初始化所有剩下的非懒加载的单例bean 初始化创建非懒加载方式的单例Bean实例(未设置属性). 填充属性 初始化方法调用(比如调用afterPropertiesSet方法、init-method方法) 调用BeanPostProcessor(后置处理器)对实例bean进行后置处 **/ finishBeanFactoryInitialization(beanFactory); // 第12步:完成Context的刷新。主要是调用LifecycleProcessor的onRefresh()方法,并且发布事件(ContextRefreshedEvent). finishRefresh(); } 。。。。。 }
3.2、bean的创建:
finishBeanFactoryInitialization(beanFactory)—>
DefaultListableBeanFactory类的preInstantiateSingletons()方法—>
AbstractBeanFactory类的getBean(String beanName),普通bean和工厂bean都是通过getBean创建的—>
AbstractBeanFactory类的doGetBean(String beanName)—>
AbstractAutowireCapableBeanFactory类的createBean(String beanName)—>doCreateBean(String beanName)
在doCreatBean()中:创建Bean实例、属性填充、调用初始化方法、执行后置处理器
// 创建Bean实例,但是还未设置属性 if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } 。。。 //初始化Bean Object exposedObject = bean; try { //属性注入 populateBean(beanName, mbd, instanceWrapper); //调用初始化方法,执行BeanPostProcessor后置处理器 exposedObject = initializeBean(beanName, exposedObject, mbd); }
再看下初始化方法中的具体操作 initializeBean()
Object wrappedBean = bean; //执行 BeanPostProcessor 的 postProcessBeforeInitialization if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { //执行初始化方法,如果Bean实现了 InitializingBean,会先调用其 afterPropertiesSet()方法 //再调用初始化方法 init() invokeInitMethods(beanName, wrappedBean, mbd); } //执行 BeanPostProcessor 的 postProcessAfterInitialization 方法 if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); }
对于Bean懒加载机制,就是在spring IOC容器初始化时不做处理,而是在第一次context.getBean()是进行初始化。
标签:初始化,BeanPostProcessor,Spring,beanName,Bean,bean,spring,原理,IOC From: https://www.cnblogs.com/jing-yi/p/18198247