源码解析
spring AOP源码解析
视频网址

一、spring IOC执行步骤

1、加载配置文件


使用BeanDefinitionReader加载 spring.xml(或注解方式、配置类、其他方式)配置文件,将其中的解析为BeanDefinition,存入beanFactory

2、配置文件增加扩展

使用 BeanFactoryPostProcessor 对xml配置类进行自定义拓展,如 修改bean等

3、创建BeanFactory(IOC容器)

也就是IOC容器或对象工厂;在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的。
由 beanFactory 创建每个类对应的单例对象, 利用了反射根据类名创建每个类的实例对象(构造,初始化方法)

4、bean实例化

初始化bean对象中:BeanPostProcessor .before 前置增加 和 BeanPostProcessor .after 后置增强
image.png

5、Demo示例

源码地址:

  • 本文源码分析基于Spring5.0.0,所以pom文件中引入5.0的依赖

    1. <dependencies>
    2. <dependency>
    3. <groupId>org.springframework</groupId>
    4. <artifactId>spring-context</artifactId>
    5. <version>5.0.0.RELEASE</version>
    6. </dependency>
    7. </dependencies>
  • 然后写一个简单的接口和实现类 ```java public interface IOCService { public String hollo(); }

public class IOCServiceImpl implements IOCService { public String hollo() { return “Hello,IOC”; } }

  1. - 新建一个application-ioc.xml
  2. ```java
  3. <?xml version="1.0" encoding="UTF-8" ?>
  4. <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xmlns="http://www.springframework.org/schema/beans"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-autowire="byName">
  7. <bean id="iocservice" class="cn.shiyujun.service.impl.IOCServiceImpl"/>
  8. </beans>
  • 启动Spring
    1. public class IOCDemo {
    2. public static void main (String args[]){
    3. ApplicationContext context = new ClassPathXmlApplicationContext("classpath:application-ioc.xml");
    4. IOCService iocService=context.getBean(IOCService.class);
    5. System.out.println(iocService.hollo());
    6. }
    7. }

二、spring Aop

1、底层原理

实际上为bean 创建一个proxy(代理:JDKproxy 或者CGLIBproxy),然后在调用bean方法时,会通过proxy来调用bean方法。

重点过程可分为:

  1. 1)通过AspectJAutoProxyBeanDefinitionParser类将AnnotationAwareAspectJAutoProxyCreator注册到Spring容器中
  2. 2AnnotationAwareAspectJAutoProxyCreator类的postProcessAfterInitialization()方法将所有有advicebean重新包装成proxy
  3. 3)调用bean方法时通过proxy来调用,proxy依次调用增强器的相关方法,来实现方法切入

2、Demo 示例

  • 引入maven依赖(笔者使用SpringBoot开发)

    1. <parent>
    2. <groupId>org.springframework.boot</groupId>
    3. <artifactId>spring-boot-starter-parent</artifactId>
    4. <version>1.5.3.RELEASE</version>
    5. </parent>
    6. <dependency>
    7. <groupId>org.springframework.boot</groupId>
    8. <artifactId>spring-boot-starter-aop</artifactId>
    9. </dependency>
  • 创建接口及其实现类

    1. public interface Person {
    2. void say();
    3. }
    4. public class Student implements Person{
    5. public void say(){
    6. System.out.println("这是一个苦逼的程序员");
    7. }
    8. }
  • 创建切面类

    1. @Aspect
    2. public class AspectJTest {
    3. @Pointcut("execution(* *.say(..))")
    4. public void test(){}
    5. @Before("test()")
    6. public void before(){
    7. System.out.println("before test..");
    8. }
    9. @After("test()")
    10. public void after(){
    11. System.out.println("after test..");
    12. }
    13. @Around("test()")
    14. public Object around(ProceedingJoinPoint p){
    15. System.out.println("before1");
    16. Object o = null;
    17. try {
    18. o = p.proceed();
    19. } catch (Throwable e) {
    20. e.printStackTrace();
    21. }
    22. System.out.println("after1");
    23. return o;
    24. }
    25. }
  • 创建beans.xml

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xmlns:aop="http://www.springframework.org/schema/aop"
    5. xsi:schemaLocation="
    6. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    7. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    8. <aop:aspectj-autoproxy/>
    9. <bean id="student" class="test.Student"/>
    10. <bean class="test.AspectJTest"/>
    11. </beans>
  • 测试类 ```java public class Test {

    public static void main(String[] args) {

    1. ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
    2. Person bean2 = (Person)ac.getBean("student");
    3. bean2.say();

    }

  1. 运行结果:
  2. ```java
  3. // 结果如下:
  4. before1
  5. before test..
  6. 这是一个苦逼的程序员
  7. after1
  8. after test..

总结:AOP功能的使用还是比较简单的,把相关bean注入到Spring容器中,编写好相应的Aspect类即可

三、要点

1、加载xml文件

  1. ApplicationContext context = new ClassPathXmlApplicationContext("classpath:application-ioc.xml");

2、ClassPathXmlApplicationContext方法

image.png
image.png

3、refresh方法

BeanFactory创建的主要流程都在里面

  1. //准备为此上下文以进行刷新
  2. prepareRefresh();
  3. // 告诉子类刷新内部bean工厂
  4. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
  5. //准备在目前情况下使用的bean工厂(BeanFactory的预准备工作)
  6. prepareBeanFactory(beanFactory);
  7. try {
  8. //允许在上下文子类中对bean工厂进行后处理
  9. postProcessBeanFactory(beanFactory);
  10. //调用在上下文中注册的bean的工厂处理器
  11. invokeBeanFactoryPostProcessors(beanFactory);
  12. // 注册拦截Bean创建的Bean处理器
  13. registerBeanPostProcessors(beanFactory);
  14. // 为此上下文初始化消息源
  15. initMessageSource();
  16. //为此上下文初始化事件多播器
  17. initApplicationEventMulticaster();
  18. // 在特定上下文子类中初始化其他特殊bean(空方法,留给子类重写使用的方法,在SpringBoot中,会将该方法重写,并且在该方法中创建了嵌入式Servlet容器实例)
  19. onRefresh();
  20. // 检查侦听器bean并注册它们
  21. registerListeners();
  22. // 实例化所有剩余的(非延迟)单例
  23. finishBeanFactoryInitialization(beanFactory);
  24. // 最后一步:发布相应的事件
  25. finishRefresh();
  26. }

4、prepareRefresh()创建前的预处理

在该方法中会有以下主要方法:

  1. //在上下文环境中初始化任何占位符属性源(空方法)
  2. initPropertySources();
  3. //验证标记为必需的所有属性都是可解析的
  4. getEnvironment().validateRequiredProperties();
  5. //允许收集早期的ApplicationEvent,一旦多播器可用时就发布
  6. this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();

initPropertySources()初始化一些占位符属性源设置,子类可以自定义个性化的属性设置;
getEnvironment().validateRequiredProperties()验证所有属性标注都是可解析的;
earlyApplicationEvents = new LinkedHashSet()保存容器中的一些早期的事件,在有了多播器后就可以被直接发布(目前我们没有设置事件,因此为null);

5、obtainFreshBeanFactory()获取BeanFactory


  1. refreshBeanFactory刷新(创建)BeanFactory,并创建了beanFactory = new DefaultListableBeanFactory();
  2. getBeanFactory()方法,返回刚刚在1中创建的BeanFactory对象; ```java protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    1. refreshBeanFactory();
    2. ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    3. if (logger.isDebugEnabled()) {
    4. logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
    5. }
    6. return beanFactory;
    }
  1. <a name="CMjIK"></a>
  2. #### 6、prepareBeanFactory(beanFactory)预准备工作
  3. BeanFactory的预准备工作(BeanFactory进行一些设置),配置工厂的标准上下文(容器)特征,例如上下文的ClassLoader和后处理器:
  4. ```java
  5. 将上一步获取的BeanFactory对象传入进来进行配置
  6. @param beanFactory the BeanFactory to configure

7、postProcessBeanFactory(beanFactory)后置处理

postProcessBeanFactory(beanFactory)该方法也是一个空方法,是为子类所留,子类通过重写该方法,可以在BeanFactory创建并预准备完成以后做进一步的设置; 这里也就是编写后置处理方法的地方;

8、invokeBeanFactoryPostProcessors(beanFactory)

该方法必须在单例实例化之前被调用;一些后置处理器的执行是会按照优先级(PriorityOrdered接口)和顺序(Ordered接口)依次执行的,最后执行没有实现任何优先级或顺序接口的BeanDefinitionRegistryPostProcessor(后置处理器)方法;

9、registerBeanPostProcessors(beanFactory)

会获取所有的BeanPostProcessor(内部bean,非我们创建的)(后置处理器默认都可以通过PriorityOrdered,Ordered接口指定优先级);
先注册(加入到beanFactory中)PriorityOrdered优先级接口的BeanPostProcessor;接着就是实现了Ordered接口,最后还是执行没有实现任何优先级或顺序接口的BeanPostProcessor;

10、initMessageSource()

初始化MessageSource组件(国际化功能,消息绑定,消息解析);

  • 【MessageSource能取出国际化配置文件中的某个key值,能按照区域信息获取】
  • 获取BeanFactory;ConfigurableListableBeanFactory beanFactory = getBeanFactory();
  • 判断容器中是否有id为MessageSource组件,如果有该组件,就直接赋值给它,如果没有就创建一个DelegatingMessageSource组件;
  • 然后把注册好的MessageSource注册在beanFactory中;
    1. beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource)

11、initApplicationEventMulticaster()

初始化事件派发器:

  • 获取beanFactory;
  • 从beanFactory获取applicationEventMulticaster的ApplicationEventMulticaster;
  • 如果没有用户未配置,就会创建一个SimpleApplicationEventMulticaster事件派发器,并将其注册到beanFactory中,以后其它组件就可以自动注入;

12、onRefresh()

留给子容器(子类),在特定子类中初始化其他特殊的bean;SpringBoot中该方法创建了嵌入式servlet容器的实例;

13、registerListeners()

给容器中将所有项目里面的ApplicationListener注册进来,


Bean的创建

14、finishBeanFactoryInitialization(beanFactory)

初始化所有剩余的(非延迟)单例(在该方法中会创建出来我们所定义出来的bean实例);

  • 1、调用beanFactory.preInstantiateSingletons();初始化所有剩余的(非延迟)单例,在这个方法中会对bean进行复杂的判断与创建,会获取bean的定义信息,判断bean是否是实现了FactoryBean的Bean等等;
  • 2、若不是实现了FactoryBean的Bean,就会调用 getBean(beanName)继续创建bean实例; ```java public void preInstantiateSingletons() throws BeansException {

    1. if (this.logger.isDebugEnabled()) {
    2. this.logger.debug("Pre-instantiating singletons in " + this);
    3. }
    4. // 依次注册新的bean定义
    5. List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
    6. // 开始所有非懒加载单例bean的初始化
    7. for (String beanName : beanNames) {
    8. RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
    9. //判断Bean不是抽象的,是单实例的并且不是懒加载的
    10. if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
    11. //判断是否是FactoryBean(工厂Bean)的(判断是否实现了FactoryBean的Bean)
    12. if (isFactoryBean(beanName)) {
    13. final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
    14. boolean isEagerInit;
    15. if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
    16. isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
    17. @Override
    18. public Boolean run() {
    19. return ((SmartFactoryBean<?>) factory).isEagerInit();
    20. }
    21. }, getAccessControlContext());
    22. }
    23. else {
    24. isEagerInit = (factory instanceof SmartFactoryBean &&
    25. ((SmartFactoryBean<?>) factory).isEagerInit());
    26. }
    27. if (isEagerInit) {
    28. getBean(beanName);
    29. }
    30. }
    31. //如果不是FactoryBean,就会利用getBean(beanName)创建对象
    32. else {
    33. getBean(beanName);
    34. }
    35. }
    36. }
    37. // 触发所有合适的bean的初始化后的回调
    38. for (String beanName : beanNames) {
    39. Object singletonInstance = getSingleton(beanName);
    40. if (singletonInstance instanceof SmartInitializingSingleton) {
    41. final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
    42. if (System.getSecurityManager() != null) {
    43. AccessController.doPrivileged(new PrivilegedAction<Object>() {
    44. @Override
    45. public Object run() {
    46. smartSingleton.afterSingletonsInstantiated();
    47. return null;
    48. }
    49. }, getAccessControlContext());
    50. }
    51. else {
    52. smartSingleton.afterSingletonsInstantiated();
    53. }
    54. }
    55. }
  1. - **3、在getBean方法中调用doGetBean(name, null, null, false)方法:先获取缓存(存在一级,二级和三级缓存)中保存的单实例Bean;如果能够获取到,说明之前已经被创建过(创建的单实例Bean都会被缓存起来);若获取不到就继续创建;**
  2. ```java
  3. // 检查单例缓存中是否有注册的单实例bean
  4. Object sharedInstance = getSingleton(beanName);
  5. if (sharedInstance != null && args == null) {
  6. if (logger.isDebugEnabled()) {
  7. if (isSingletonCurrentlyInCreation(beanName)) {
  8. logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
  9. "' that is not fully initialized yet - a consequence of a circular reference");
  10. }
  11. else {
  12. logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
  13. }
  14. }
  15. bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
  16. }
  • 4、在缓存中如果没有,说明是没有创建的bean,就会调用createBean(beanName, mbd, args)来继续创建; ```java // Create bean instance.
    1. if (mbd.isSingleton()) {
    2. sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
    3. @Override
    4. public Object getObject() throws BeansException {
    5. try {
    6. //创建Bean实例
    7. return createBean(beanName, mbd, args);
    8. }
    9. catch (BeansException ex) {
    10. destroySingleton(beanName);
    11. throw ex;
    12. }
    13. }
    14. });
    15. bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    16. }
  1. 5、在createBean方法中的中会有resolveBeforeInstantiation(beanName,mbd)方法,该方法会给bean的后置处理器一个返回代理对象而不是目标bean实例的机会;让BeanPostProcessor先拦截返回代理对象:
  2. - InstantiationAwareBeanPostProcessor的执行;
  3. - 先执行postProcessBeforeInstantiation(beanClass, beanName)方法,如果有返回值再去执行postProcessAfterInitialization(result, beanName)方法;
  4. [<br />](https://blog.csdn.net/qq_43816409/article/details/105922639)
  5. ```java
  6. //使用实例化之前的后处理器,以解决指定bean实例化之前是否存在的快捷方式
  7. protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
  8. Object bean = null;
  9. if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
  10. // Make sure bean class is actually resolved at this point.
  11. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
  12. Class<?> targetType = determineTargetType(beanName, mbd);
  13. if (targetType != null) {
  14. //前置实例化处理
  15. bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
  16. if (bean != null) {
  17. //后置实例化处理
  18. bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
  19. }
  20. }
  21. }
  22. mbd.beforeInstantiationResolved = (bean != null);
  23. }
  24. return bean;
  25. }

6、如果上一步没有返回代理对象时,就会调用如下方法继续创建:

  1. Object beanInstance = doCreateBean(beanName, mbdToUse, args);/创建Bean

doGetBean方法:
在doGetBean方法中调用createBean,然后再createBean中再调用doCreateBean方法;

1、在doCreateBean方法中创建Bean的实例:createBeanInstance(beanName, mbd, args);利用工厂方法或确定对象的构造器创建出Bean实例;

2、applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName),允许Bean的后置处理器来修改bean的定义;

3、populateBean(beanName, mbd, instanceWrapper)开始给Bean属性进行赋值:

赋值之前:
获取到InstantiationAwareBeanPostProcessor后置处理器,执行postProcessAfterInstantiation方法;
再获取到InstantiationAwareBeanPostProcessor后置处理器,执行postProcessPropertyValues方法;
赋值:
应用Bean的属性值,为属性利用setter方法进行赋值:applyPropertyValues(beanName, mbd, bw, pvs);

Bean初始化:initializeBean(beanName, exposedObject, mbd):

1、执行Aware接口的方法】执行invokeAwareMethods(beanName, bean)方法,也就是执行BeanNameAware、BeanClassLoaderAware和BeanFactoryAware方法(xxxAware方法);

  1. private void invokeAwareMethods(final String beanName, final Object bean) {
  2. if (bean instanceof Aware) {
  3. if (bean instanceof BeanNameAware) {
  4. ((BeanNameAware) bean).setBeanName(beanName);
  5. }
  6. if (bean instanceof BeanClassLoaderAware) {
  7. ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
  8. }
  9. if (bean instanceof BeanFactoryAware) {
  10. ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
  11. }
  12. }
  13. }

2、执行后置处理器初始化之前的方法(预初始化方法)】调用applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)方法,然后再调用BeanPostProcessor.postProcessBeforeInitialization(result, beanName)方法;
3、【执行初始化方法】invokeInitMethods(beanName, wrappedBean, mbd):
判断是否是InitializingBean接口的实现,执行接口规定的初始化;
判断是否自定义初始化方法,如果有就执行;
4、【执行后置处理器初始化后方法】applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName),然后执行beanProcessor.postProcessAfterInitialization(result, beanName)方法;

  1. protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
  2. if (System.getSecurityManager() != null) {
  3. AccessController.doPrivileged(new PrivilegedAction<Object>() {
  4. @Override
  5. public Object run() {
  6. invokeAwareMethods(beanName, bean);
  7. return null;
  8. }
  9. }, getAccessControlContext());
  10. }
  11. else {
  12. //执行Aware接口的方法
  13. invokeAwareMethods(beanName, bean);
  14. }
  15. Object wrappedBean = bean;
  16. if (mbd == null || !mbd.isSynthetic()) {
  17. //【执行后置处理器初始化之前的方法(预初始化方法)】
  18. wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
  19. }
  20. try {
  21. //【执行初始化方法】
  22. invokeInitMethods(beanName, wrappedBean, mbd);
  23. }
  24. catch (Throwable ex) {
  25. throw new BeanCreationException(
  26. (mbd != null ? mbd.getResourceDescription() : null),
  27. beanName, "Invocation of init method failed", ex);
  28. }
  29. if (mbd == null || !mbd.isSynthetic()) {
  30. //【执行后置处理器初始化后方法】
  31. wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
  32. }
  33. return wrappedBean;
  34. }

5.在上述的doCreateBean方法返回创建好的exposedObject(bean实例),最终在doGetBean中会返回创建的bean:
image.png
6、在doCreateBean方法中注册Bean的销毁方法(不是执行)registerDisposableBeanIfNecessary(beanName, bean, mbd);

将创建的Bean实例添加到缓存( Map singletonObjects = new ConcurrentHashMap(256))中;

上述是Bean实例的创建过程。

15、finishRefresh()

完成BeanFactory的初始化创建工作,IOC容器就会创建完毕:

  • initLifecycleProcessor(),初始化和声明周期有关的处理器;
  • getLifecycleProcessor().onRefresh(),获取到之前定义的生命周期处理器(BeanFactory),回调onRefresh方法;
  • publishEvent(new ContextRefreshedEvent(this)),发布容器刷新完成事件;
  • LiveBeansView.registerApplicationContext(this)。