• Spring(SpringBoot)--AOP的原理(二)--源码分析


    原文网址:Spring(SpringBoot)--AOP的原理(二)--源码分析_IT利刃出鞘的博客-CSDN博客

    简介

    说明

            本文通过源码来分析Spring的AOP的原理。

    相关网址

    Spring(SpringBoot)--AOP的原理(一)--概述_IT利刃出鞘的博客-CSDN博客_springboot的aop原理

    1.启用AOP

    简介

            spring-boot-starter-aop如何做到自动配置的?见:SpringBoot原理--自动配置_feiying0canglang的博客-CSDN博客

            要使用AOP,首先要引入包。如果引入的是spring-aop包,则需要使用@EnableAspectJAutoProxy开启aop功能;如果引入的是spring-boot-starter-aop,则AOP就直接可以用了,无需加注解之类的开启它。

            实际上,spring-boot-starter-aop是自动用了@EnableAspectJAutoProxy,所以我们还是从@EnableAspectJAutoProxy开始。

    @EnableAspectJAutoProxy

    EnableAspectJAutoProxy注解类上用了: @Import({AspectJAutoProxyRegistrar.class})

    1. @Target({ElementType.TYPE})
    2. @Retention(RetentionPolicy.RUNTIME)
    3. @Documented
    4. @Import({AspectJAutoProxyRegistrar.class})
    5. public @interface EnableAspectJAutoProxy {
    6. boolean proxyTargetClass() default false;
    7. boolean exposeProxy() default false;
    8. }
    • proxyTargetClass 指定是否使用CGLIB的方式创建实现接口的目标对象的代理。缺省值为true,使用CGLIB方式创建对象的代理。

    • exposeProxy  标记代理对象是否应该被aop框架通过AopContext以ThreadLocal的形式暴露出去。当一个代理对象需要调用它自己的另外一个代理方法时,这个属性将非常有用。默认是是false,以避免不必要的拦截。

    AspectJAutoProxyRegistrar

    总结

    AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar,实现registerBeanDefinitions方法

    向容器中注册bean:org.springframework.aop.config.internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator

    注册AnnotationAwareAspectJAutoProxyCreator

    追踪:AspectJAutoProxyRegistrar#registerBeanDefinitions  //从名字就可以看出来,它是注册BeanDefinition用的。

    registerBeanDefinitions //AspectJAutoProxyRegistrar
        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); //AspectJAutoProxyRegistrar.java
            registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, (Object)null); //AopConfigUtils.class
                registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source); //AopConfigUtils.class

    AopConfigUtils#registerOrEscalateApcAsRequired

    1. private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
    2. Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    3. if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
    4. BeanDefinition apcDefinition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
    5. if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
    6. int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
    7. int requiredPriority = findPriorityForClass(cls);
    8. if (currentPriority < requiredPriority) {
    9. apcDefinition.setBeanClassName(cls.getName());
    10. }
    11. }
    12. return null;
    13. } else {
    14. RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
    15. beanDefinition.setSource(source);
    16. beanDefinition.getPropertyValues().add("order", -2147483648);
    17. beanDefinition.setRole(2);
    18. registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
    19. return beanDefinition;
    20. }
    21. }

    开始的时候AutoProxyCreator类不存在,RootBeanDefinition初始化AnnotationAwareAspectJAutoProxyCreator类,注册类到IOC容器。

    创建AnnotationAwareAspectJAutoProxyCreator

    相关网址

    refresh()BeanPostProcessor

    总结 

     AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor接口与Ordered接口(值为32位int的最大值),它在registerBeanPostProcessors()中处理,最终被实例化、设置属性、初始化。

    分析

    在上边“重要的类”可以得出:AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor接口与Ordered接口(值为32位int的最大值),那它会在registerBeanPostProcessors()中处理:

    AbstractApplicationContext#refresh()
        registerBeanPostProcessors(beanFactory) //AbstractApplicationContext
            PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
                BeanPostProcessor pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
                    getBean(String name, Class<T> requiredType)   //AbstractBeanFactory
                        doGetBean(name, requiredType, null, false) //AbstractBeanFactory
                            createBean(beanName, mbd, args); //AbstractAutowireCapableBeanFactory
                                doCreateBean(beanName, mbdToUse, args);  //AbstractAutowireCapableBeanFactory

    AbstractAutowireCapableBeanFactory#doCreateBean(beanName, mbdToUse, args); 主要做了如下几件事:

    创建bean :createBeanInstance(beanName, mbd, args)
    给bean中的属性赋值:populateBean(beanName, mbd, instanceWrapper)
    初始化bean:initializeBean(beanName, exposedObject, mbd)

    1. protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
    2. throws BeanCreationException {
    3. // Instantiate the bean.
    4. // 实例化bean
    5. BeanWrapper instanceWrapper = null;
    6. if (mbd.isSingleton()) {
    7. instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    8. }
    9. if (instanceWrapper == null) {
    10. instanceWrapper = createBeanInstance(beanName, mbd, args);
    11. }
    12. final Object bean = instanceWrapper.getWrappedInstance();
    13. Class<?> beanType = instanceWrapper.getWrappedClass();
    14. if (beanType != NullBean.class) {
    15. mbd.resolvedTargetType = beanType;
    16. }
    17. // Allow post-processors to modify the merged bean definition.
    18. // 允许post-processors来修改合并的bean定义
    19. synchronized (mbd.postProcessingLock) {
    20. if (!mbd.postProcessed) {
    21. try {
    22. applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
    23. } catch (Throwable ex) {
    24. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    25. "Post-processing of merged bean definition failed", ex);
    26. }
    27. mbd.postProcessed = true;
    28. }
    29. }
    30. // Eagerly cache singletons to be able to resolve circular references
    31. // even when triggered by lifecycle interfaces like BeanFactoryAware.
    32. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
    33. isSingletonCurrentlyInCreation(beanName));
    34. if (earlySingletonExposure) {
    35. if (logger.isTraceEnabled()) {
    36. logger.trace("Eagerly caching bean '" + beanName +
    37. "' to allow for resolving potential circular references");
    38. }
    39. addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    40. }
    41. // Initialize the bean instance.
    42. // 初始化bean
    43. Object exposedObject = bean;
    44. try {
    45. populateBean(beanName, mbd, instanceWrapper);
    46. exposedObject = initializeBean(beanName, exposedObject, mbd);
    47. }
    48. catch (Throwable ex) {
    49. if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
    50. throw (BeanCreationException) ex;
    51. } else {
    52. throw new BeanCreationException(
    53. mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
    54. }
    55. }
    56. if (earlySingletonExposure) {
    57. Object earlySingletonReference = getSingleton(beanName, false);
    58. if (earlySingletonReference != null) {
    59. if (exposedObject == bean) {
    60. exposedObject = earlySingletonReference;
    61. } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
    62. String[] dependentBeans = getDependentBeans(beanName);
    63. Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
    64. for (String dependentBean : dependentBeans) {
    65. if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
    66. actualDependentBeans.add(dependentBean);
    67. }
    68. }
    69. if (!actualDependentBeans.isEmpty()) {
    70. throw new BeanCurrentlyInCreationException(beanName,
    71. "Bean with name '" + beanName + "' has been injected into other beans [" +
    72. StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
    73. "] in its raw version as part of a circular reference, but has eventually been " +
    74. "wrapped. This means that said other beans do not use the final version of the " +
    75. "bean. This is often the result of over-eager type matching - consider using " +
    76. "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
    77. }
    78. }
    79. }
    80. }
    81. // Register bean as disposable.
    82. try {
    83. registerDisposableBeanIfNecessary(beanName, bean, mbd);
    84. } catch (BeanDefinitionValidationException ex) {
    85. throw new BeanCreationException(
    86. mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    87. }
    88. return exposedObject;
    89. }

    2.生成代理对象

    3.执行目标方法

  • 相关阅读:
    远程监控电脑软件怎么选?
    程序员的数学课01 从计数开始,程序员必知必会的数制转换法
    【Linux】计算机的软硬件体系结构
    李沐_动手学深度学习_19_卷积层
    模块化设计的耳机,找到属于你的色彩,魔尼悉比Rainbow耳机体验
    [数据结构] 树与二叉树
    python学习--定义python中的类
    【Python】queue模块Queue对象
    99页4万字XX大数据湖项目建设方案
    工薪族创业方案
  • 原文地址:https://blog.csdn.net/feiying0canglang/article/details/125382612