Spring中Bean的生命周期以及IOC与AOP加载过程

  • Post author:
  • Post category:其他


首先说一下Bean的生命周期

Bean的生命周期


创建Bean >> 初始化 >> 摧毁


1.创建Bean

当设置Bean为单例时,在spring容器启动时会创建Bean。

当设置Bean为多例是,在调用Bean时才会被创建。


2.初始化

使用init()来完成Bean的初始化操作,在初始化环节中,可以使用BeanPostProcesser(后置处理器),对Bean进行一系列的操作。


3.摧毁

destroy()

单例模式下,在容器关闭时会调用destroy()进行摧毁。

多例模式下,bean不会被摧毁,也不会调用destroy方法。


IOC加载过程

spring启动时会进入

注解AnnotationConfigApplicationContext()方法

AnnotationConfigApplicationContext()方法中

首先调用this()方法,初始化读取器和扫描器

然后调用register(),注册bean配置类

XML配置ClassPathXmlApplicationContext()方法

ClassPathXmlApplicationContext()方法中

super(parent)

setConfigLocations(configLocations)

无论是哪种方式最后都会进入refresh()方法,也是Spring初始化过程的重点

进入refresh方法

方法内使用synchronized锁即将要操作的代码块进行加锁,保证不会被重复初始化,此时的锁的对象是一个final修饰的Object对象

进到同步代码块内有十几个方法(12),方法如下:


1.prepareRefresh()  准备初始化

方法内主要设置了容器的启动时间和启动标识,校验属性的合法性等。


2.obtainFreshBeanFactory()  获取BeanFactory

方法内主要对已有的Bean进行摧毁,关闭BeanFactory,并创建新的BeanFactory。然后解析配置文件,形成BeanDefinition对象,存储起来。


3.prepareBeanFactory()  准备BeanFactory

方法内都是Spring的特殊处理,主要对设置了BeanFactory的类加载器,注册几个Bean的后置处理器,忽略指定的Bean,注册指定的Bean。


4.postProcesserBeanFactory()  Bean工厂的后置处理器

这个方法是留给子类扩展的,子类可以通过添加一些特殊了BeanFactoryPostProcesser实现类,来完成一些其他操作。


5.invokeBeanFactoryPostProcesser()  执行Bean工厂后置处理器

方法主要功能是调用BeanFactoryPostProcesser实现类的postProcessBeanFactory方法。


6.registerBeanPostProcessors()  注册bean的后置处理器

方法内主要是注册BeanPostProcesser的实现类,

注册顺序:

①实现PriorityOrdered接口

②实现Ordered接口

③没有实现任何优先接口

④实现MergedBeanDefinitionPostProcessor接口

registerBeanPostProcessors方法所在的类有一个内部类BeanPostProcessorChecker,它里面有两个方法 PostProcesserBeforeInitialization (初始化之前执行)和PostProcesserAfterInitialization(初始化之后执行)。

注:AOP是在这里被注册的


7.initMessageSource()  初始化MessageSource  国际化处理


8.initApplicationEventMulticaster()  初始化事件派发器


9.onRefresh()  自定义刷新

子类重写这个方法,在容器刷新的时候可以自定义逻辑。


10.registerListeners()  注册监听器


11.finishBeanFactoryInitialization(beanFactory)  完成BeanFactory初始化

程序执行到当前方法时已经执行了所有的BeanFactory后置处理器,并且加载了一些特殊的bean。这个方法主要会初始化剩下的没有设置成懒加载模式的所有单例Bean。


12.finishRefresh() 完成刷新

方法内初始化生命周期后置处理器,发布容器刷新完成事件。

AOP创建过程


开启AOP的两种方式


1.

注解 @EnableAspestJAutoProxy

前置通知(@Before):logStart:在目标方法div()运行之前运行
后置通知(@After):logEnd:在目标方法div()运行结束之后运行
返回通知(@AfterReturning):logReturn:在目标方法div()正常返回之后运行
异常通知(@AfterThrowing):logException:在目标方法div()出现异常之后运行


2.

XML配置……

    <!-- 定义切面 -->
    <bean name="myAspectXML" class="com.zejian.spring.springAop.AspectJ.MyAspectXML" />
    <!-- 配置AOP 切面 -->
    <aop:config>
        <!-- 定义切点函数 -->
        <aop:pointcut id="pointcut" expression="execution(* com.zejian.spring.springAop.dao.ProductDao.add(..))" />

        <!-- 定义其他切点函数 -->
        <aop:pointcut id="delPointcut" expression="execution(* com.zejian.spring.springAop.dao.ProductDao.delete(..))" />

        <!-- 定义通知 order 定义优先级,值越小优先级越大-->
        <aop:aspect ref="myAspectXML" order="0">
            <!-- 定义通知   method 指定通知方法名,必须与MyAspectXML中的相同  pointcut 指定切点函数-->
            <aop:before method="before" pointcut-ref="pointcut" />

            <!-- 后置通知  returning="returnVal" 定义返回值 必须与类中声明的名称一样-->
            <aop:after-returning method="afterReturn" pointcut-ref="pointcut"  returning="returnVal" />

            <!-- 环绕通知 -->
            <aop:around method="around" pointcut-ref="pointcut"  />

            <!--异常通知 throwing="throwable" 指定异常通知错误信息变量,必须与类中声明的名称一样-->
            <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="throwable"/>

            <!-- method : 通知的方法(最终通知)  pointcut-ref : 通知应用到的切点方法 -->
            <aop:after method="after" pointcut-ref="pointcut"/>
        </aop:aspect>
    </aop:config>

AOP创建过程


1.

registerBeanPostProcessors() 注册后置处理器;创建AnnotationAwareAspectJAutoProxyCreator


2.

finishBeanFactoryInitialization() 初始化剩下的单实例bean

2.1 创建业务逻辑和切面组件

2.2 AnnotationAwaretJAutoProxyCreator拦截组件的创建过程

2.3 组件创建完之后,判断组件是否需要增强

是:切面的通知方法,包装成增强器(Advisor);给业务逻辑组件创建一个代理对象


3.

执行目标方法:


3.1

代理对象执行目标方法


3.2

CglibAopProxy.intercept();


3.2.1

得到目标方法的拦截器链(增强器包装成拦截器MethodInterceptor)


3.2.2

利用连接器的链式机制,依次进入每一个拦截器进行执行;


3.2.3

效果:

正常执行:前置通知->目标方法->后置通知->返回通知

出现异常:前置通知->目标方法->后置通知->异常通知



版权声明:本文为ysl19910806原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。