您当前的位置: 首页 >  spring

止步前行

暂无认证

  • 0浏览

    0关注

    247博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Spring源码系列(九)——AOP动态代理源码分析

止步前行 发布时间:2021-11-07 14:27:25 ,浏览量:0

文章目录
  • 一、Spring启动流程再分析
    • 1. 处理Import过程
    • 2. 执行Import导入类
  • 二、AOP源码分析
    • 1. AspectJAutoProxyRegistrar类
    • 2. internalAutoProxyCreator类
    • 3. BeanPostProcessor方法执行
  • 三、小结
AOP的原理实现和Mybatis整合进Spring中的原理实现一模一样,下面来具体分析一下。在看这篇之前,建议先看下上一篇。

Spring源码系列(八)——Mybatis是如何整合进Spring源码分析

https://blog.csdn.net/zxd1435513775/article/details/121180974

一、Spring启动流程再分析

配置类,开启AOP的注解@EnableAspectJAutoProxy

@Configuration
@ComponentScan("com.scorpios")
@EnableAspectJAutoProxy
public class AppConfig {
 
}

切面类

@Aspect
@Component
public class AspectJScorpios {

    @Pointcut("execution(* com.scorpios.service..*.*(..))")
    public void pointCut(){

    }

    @Before("pointCut()")
    public void before(){
        System.out.println(" proxy before ... ");
    }
}

启动类

public static void main( String[] args )
{
    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
    ac.register(AppConfig.class);
    ac.refresh();
    XService xService = (XService) ac.getBean("XService");
    xService.print();
}
1. 处理Import过程

对于Import的处理过程,可以看一下源码分析第四篇,包扫描中处理@Import注解部分。

Spring源码系列(四)——ConfigurationClassPostProcessor功能解析

https://blog.csdn.net/zxd1435513775/article/details/120935494

@EnableAspectJAutoProxy注解源码,使用@Import注解,向Spring容器中导入AspectJAutoProxyRegistrar类,而AspectJAutoProxyRegistrar类实现ImportBeanDefinitionRegistrar接口。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

	boolean proxyTargetClass() default false;
    
	boolean exposeProxy() default false;
    
}

关于@Import注解导入ImportBeanDefinitionRegistrar实现类的介绍可以看一下Spring源码系列(八),

AOP的原理和Mybatis的原理一样,都是通过实现ImportBeanDefinitionRegistrar接口,Mybatis的实现类是MapperScannerRegistrar,而AOP的实现类是AspectJAutoProxyRegistrar

// Mybatis

class MapperScannerRegistrar implements ImportBeanDefinitionRegistrar

// AOP

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar

2. 执行Import导入类

parser.parse(candidates);这行代码里完成了对@Import注解的导入工作,并对实现ImportBeanDefinitionRegistrar接口的类完成了实例化,并把已经创建好的实列放到了ConfigurationClass类的属性importBeanDefinitionRegistrars中,可以看下面断点图。

在这里插入图片描述

this.reader.loadBeanDefinitions()这个方法中完成了对ImportBeanDefinitionRegistrar接口方法的调用。

下面就来看一下AspectJAutoProxyRegistrar类中实现ImportBeanDefinitionRegistrar接口的方法了。AOP的入口就在这里!!!!

二、AOP源码分析 1. AspectJAutoProxyRegistrar类

来看一下AspectJAutoProxyRegistrar类中实现ImportBeanDefinitionRegistrar接口方法。

该方法的作用就是往Spring容器中添加一个BeanDefinitionbeanNameorg.springframework.aop.config.internalAutoProxyCreatorbeanClassAnnotationAwareAspectJAutoProxyCreator.class

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(
        AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

        // 核心方法
        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);
            }
        }
    }
}

public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
    return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}


public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
    BeanDefinitionRegistry registry, @Nullable Object source) {

    return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}


private static BeanDefinition registerOrEscalateApcAsRequired(
    Class cls, BeanDefinitionRegistry registry, @Nullable Object source) {

    if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
        BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
        if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
            int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
            int requiredPriority = findPriorityForClass(cls);
            if (currentPriority  {
            invokeAwareMethods(beanName, bean);
            return null;
        }, getAccessControlContext());
    } else {
        // 执行setBeanName/setBeanFactory赋值
        invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        // 调用BeanPostProcessor接口中的postProcessBeforeInitialization()方法
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
        // 执行自定义的init-method方法
        invokeInitMethods(beanName, wrappedBean, mbd);
    } catch (Throwable ex) {
       // 抛异常代码略
    }
    if (mbd == null || !mbd.isSynthetic()) {
        // 调用BeanPostProcessor接口中的postProcessAfterInitialization()方法
        // AOP代理就在AnnotationAwareAspectJAutoProxyCreator类此方法中
        // AnnotationAwareAspectJAutoProxyCreator的父类AbstractAutoProxyCreator实现了此方法
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}

上面这个AnnotationAwareAspectJAutoProxyCreator类中的postProcessAfterInitialization()方法执行过后,XService实例就变成了Cglib代理对象了。

在这里插入图片描述

下面来分析下源码:

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    if (bean != null) {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (this.earlyProxyReferences.remove(cacheKey) != bean) {
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
        return bean;
    }
    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
        return bean;
    }
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    if (specificInterceptors != DO_NOT_PROXY) {
        this.advisedBeans.put(cacheKey, Boolean.TRUE);
        // 创建代理对象
        Object proxy = createProxy(
            bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
        this.proxyTypes.put(cacheKey, proxy.getClass());
        return proxy;
    }

    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;
}
protected Object createProxy(Class beanClass, @Nullable String beanName,
                             @Nullable Object[] specificInterceptors, TargetSource targetSource) {

    if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
        AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
    }

    ProxyFactory proxyFactory = new ProxyFactory();
    proxyFactory.copyFrom(this);

    if (!proxyFactory.isProxyTargetClass()) {
        if (shouldProxyTargetClass(beanClass, beanName)) {
            proxyFactory.setProxyTargetClass(true);
        }
        else {
            evaluateProxyInterfaces(beanClass, proxyFactory);
        }
    }

    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    proxyFactory.addAdvisors(advisors);
    proxyFactory.setTargetSource(targetSource);
    customizeProxyFactory(proxyFactory);

    proxyFactory.setFrozen(this.freezeProxy);
    if (advisorsPreFiltered()) {
        proxyFactory.setPreFiltered(true);
    }

    return proxyFactory.getProxy(getProxyClassLoader());
}


public Object getProxy(@Nullable ClassLoader classLoader) {
    return createAopProxy().getProxy(classLoader);
}

protected final synchronized AopProxy createAopProxy() {
    if (!this.active) {
        activate();
    }
    return getAopProxyFactory().createAopProxy(this);
}

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    // 这个判断很重要,可以通过配置文件进行配置,来决定采用什么动态代理
    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
        Class targetClass = config.getTargetClass();
        if (targetClass == null) {
			// 抛异常略
        }
        if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
            // 创建JDK动态代理
            return new JdkDynamicAopProxy(config);
        }
        // 创建Cglib动态代理
        return new ObjenesisCglibAopProxy(config);
    }
    else {
        return new JdkDynamicAopProxy(config);
    }
}
三、小结

AOP的原理和Mybatis的原理一样,都是利用了Spring@Import导入ImportBeanDefinitionRegistrar这个扩展点。先往容器中添加一个BeanDefinition,然后再适当的时机进行方法的调用。

两篇文章可以对比着看。

关注
打赏
1657848381
查看更多评论
立即登录/注册

微信扫码登录

0.0454s