Spring5.0源码深度解析之SpringBean的Aop源码分析

SpringAop源码分析:需要关联SpringBean的生命周期

思考:

1.什么时候创建代理类对象 2.SpringAop中如何综合运用CGLIB和JDK动态代理

@EnableAspectJAutoProxy:开启AOP的权限

注入到Spring容器中

ImportBeanDefinitionRegistrar手动注册Bean对象

在前几章中提过,实现ImportBeanDefinitionRegistrar这个接口,可以自己手动注册一些Bean到Spring容器中

AspectJAutoProxyRegistrar实现了ImportBeanDefinitionRegistrar就可以手动注册Bean对象

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

   @Override
   public void registerBeanDefinitions(
         AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
       //这里手动注册Bean
      AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
      AnnotationAttributes enableAspectJAutoProxy =
            AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
      if (enableAspectJAutoProxy != null) {
         if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
            AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
         }
         if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
            AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
         }
      }
   }
}
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
    return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, (Object)null);
}
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {
    return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
AnnotationAwareAspectJAutoProxyCreator.class
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
        BeanDefinition apcDefinition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
        if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
            int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
            int requiredPriority = findPriorityForClass(cls);
            if (currentPriority < requiredPriority) {
                apcDefinition.setBeanClassName(cls.getName());
            }
        }
        return null;
    } else {
        RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
        beanDefinition.setSource(source);
        beanDefinition.getPropertyValues().add("order", -2147483648);
        beanDefinition.setRole(2);
        registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);//注册IOC容器中
        return beanDefinition;
    }
}

综上:总结下

1.@EnableAspectJAutoProxy:开启AOP的权限 2.@Import(AspectJAutoProxyRegistrar.class)注入到容器中,手动注册切面类 3.AnnotationAwareAspectJAutoProxyCreator需要将这个类注入到IOC容器中 4.registerBeanDefinition注册Bean信息内容: ##BeanId=org.springframework.aop.config.internalAutoProxyCreator ##class:AnnotationAwareAspectJAutoProxyCreator

我们打印下注册的Bean

1无参构造函数....说明对象初开始始化了 2执行自定义bean的init方法 beanDefinitionNames[i]:org.springframework.context.annotation.internalConfigurationAnnotationProcessor beanDefinitionNames[i]:org.springframework.context.annotation.internalAutowiredAnnotationProcessor beanDefinitionNames[i]:org.springframework.context.annotation.internalRequiredAnnotationProcessor beanDefinitionNames[i]:org.springframework.context.annotation.internalCommonAnnotationProcessor beanDefinitionNames[i]:org.springframework.context.event.internalEventListenerProcessor beanDefinitionNames[i]:org.springframework.context.event.internalEventListenerFactory beanDefinitionNames[i]:myConfig beanDefinitionNames[i]:memberServiceImpl beanDefinitionNames[i]:payService beanDefinitionNames[i]:loginAop beanDefinitionNames[i]:org.springframework.aop.config.internalAutoProxyCreator //这个就是我们注入的Bean

后面我们需要了解SpringAOP底层是如何实现的 离不开AnnotationAwareAspectJAutoProxyCreator

下面看看AnnotationAwareAspectJAutoProxyCreator类图结构

得出结论:AnnotationAwareAspectJAutoProxyCreator的祖宗是BeanPostProcessors

BeanPostProcessors是对我们的Bean的初始化方法实现增强。由Java多态,可知AnnotationAwareAspectJAutoProxyCreator也是可以实现对Bean初始化方法增强。

所以AnnotationAwareAspectJAutoProxyCreator本质就是对init方法实现增强

public interface BeanPostProcessor {
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {//init方法前置处理
        return bean;
    }

    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {//init方法后置处理
        return bean;
    }
}

AnnotationAwareAspectJAutoProxyCreator的前置和后置在AbstractAutoProxyCreator实现类中实现

前置处理器:没做任何事

public Object postProcessBeforeInitialization(Object bean, String beanName) {
    return bean;
}

后置处理器:具体做事情,使用后置处理器实现代理对象的创建

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
    if (bean != null) {
        Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
        if (!this.earlyProxyReferences.contains(cacheKey)) {
            return this.wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}

因为前置没做任何事情,我们可以debug到后置处理器,实现代理类对象的创建。

也就是任何Bean对象在初始化之前,都会调用AbstractAutoProxyCreator的后置处理创建代理类对象

if (mbd == null || !mbd.isSynthetic()) {
    wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
    if (bean != null) {
        Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
        if (!this.earlyProxyReferences.contains(cacheKey)) {
            return this.wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}

获得五个通知

创建代理类

public Object getProxy(@Nullable ClassLoader classLoader) {
    return this.createAopProxy().getProxy(classLoader);
}
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
        return new JdkDynamicAopProxy(config);
    } else {
        Class<?> targetClass = config.getTargetClass();
        if (targetClass == null) {
            throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.");
        } else {
            return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
        }
    }
}

总结:

被代理对象在初始化的时候,AbstractAutoProxyCreator 经过这样的一个类拦截。 判断该被代理对象是否有被有实现过接口,如果有实现过接口就使用jdk动态代理,如果没有实现接口则使用cglib动态代理。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券