SpringAOP源码读书笔记

1、首先配置类里面需要加入注解EnableAspectJAutoProxy,后面的(proxyTargetClass = true)涉及到动态代理的类型后面会解释

  Configuration和ComponentScan以及Component注解这边就不赘述了;

package com.aop;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.ImportResource;
import org.springframework.stereotype.Component;
@Configuration
@Component("app")
@ComponentScan("com.aop")
@EnableAspectJAutoProxy//(proxyTargetClass = true)
public class AopConfig {

}


2、我们进入到EnableAspectJAutoProxy里面可以看出这个类里面通过@Import的形式注入了一个类:AspectJAutoProxyRegistrar;

@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {


3、进入到这个类发现他实现了我们大名鼎鼎的ImportBeanDefinitionRegistrar接口,熟悉Spring代码的同学都知道;Spring初始化期间,会调用实现了ImportBeanDefinitionRegistrar的类里面的registerBeanDefinitions方法,所以我们看这个方法:registerAspectJAnnotationAutoProxyCreatorIfNecessary

package org.springframework.context.annotation;
import org.springframework.aop.config.AopConfigUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
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); } } } }


4、一直跟踪这个函数我们会发现最终会执行到这个函数里面:registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);会把AnnotationAwareAspectJAutoProxyCreator注册到beanDefinitionMap里面,名称是:org.springframework.aop.config.internalAutoProxyCreator

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

        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");

        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 < requiredPriority) {
                    apcDefinition.setBeanClassName(cls.getName());
                }
            }
            return null;
        }

        RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
        beanDefinition.setSource(source);
        beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
        beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
        registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
        return beanDefinition;
    }
public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
            "org.springframework.aop.config.internalAutoProxyCreator";

5、到这里我们需要来看Spring实例化的过程了:首先会有一个测试类;annotationConfigApplicationContext.register(AopConfig.class);及其之前的代码就不再解释了,这边就是创建了一个bean工厂(DefaultListableBeanFactory类型的),然后会向工厂里面注册我们的配置类以及6个类;

package com.aop;

import com.config.AppConfig;
import com.luban.dao.UserDao;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class TestAop {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
        annotationConfigApplicationContext.register(AopConfig.class);
        annotationConfigApplicationContext.refresh();
        AopDao dao = (AopDao) annotationConfigApplicationContext.getBean("aopdao");
        dao.test();

    }
}

 

6、我们来看annotationConfigApplicationContext.refresh();里面执行的代码逻辑(此处中间的逻辑只简单的说明一下,主要看我们的AOP是如何实现的)

refresh方法里面会执行invokeBeanFactoryPostProcessors(beanFactory);之前的方法都是做了一些初始化,这二个方法里面完成了Bean的扫描并放到了beanDefinitionMap里面;这个方法会在处理完Import的类以后结束;有关于Spring中间的实例化过程会在后面的文章中分享;让我们看AOP的过程;

invokeBeanFactoryPostProcessors(beanFactory);

7、在对象创建完成以后会执行一个方法:这个方法传入的参数是bean的name和实例化以后的对象以及BeanDefinition;在这个方法里面会执行后置处理器的before和after方法,这边会遍历我们环境中的所有的后置处理器;其中有一个后置处理器是我们上面第4步的时候注册进去的;看下面截图:

exposedObject = initializeBean(beanName, exposedObject, mbd);
@Override
    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
            throws BeansException {

        Object result = existingBean;
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            Object current = processor.postProcessBeforeInitialization(result, beanName);
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }

    @Override
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
            throws BeansException {

        Object result = existingBean;
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            Object current = processor.postProcessAfterInitialization(result, beanName);
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }

当遍历到这个后置处理器的时候,在postProcessAfterInitialization方法里面,会通过wrapIfNecessary方法返回一个对象,进入到这个方法可以看出里面调用了

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

进入到这个方法可以看出里面调用了

Object proxy = createProxy(
                    bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));

来看一下createProxy方法:方法里面前面的isProxyTargetClass()就是判断配置类里面的下面的这个注解后面是为true还是false

@EnableAspectJAutoProxy//(proxyTargetClass = true)

看这个方法里面最后面一句:

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);
    }

下面这边厉害了,请看代码:这边就解释了为社么SpringAOP动态代理有的时候用的是JDK,有的时候用的是CGLIB

@Override
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
            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.");
            }
            //如果对象所属的类是接口
            if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
                //采用的是JDK动态代理
                return new JdkDynamicAopProxy(config);
            }
            //采用的是CGLIB代理
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            //采用的是JDK动态代理
            return new JdkDynamicAopProxy(config);
        }
    }

猜你喜欢

转载自www.cnblogs.com/ychuang/p/10419056.html