spring AOP源码实现分析

postProcessBeforeInstantiation

AbstractAutoProxyCreator#postProcessBeforeInstantiation 是在实例化之前执行的后置处理器
调用链执行在Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            // Make sure bean class is actually resolved at this point.
            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                Class targetType = determineTargetType(beanName, mbd);
                if (targetType != null) {
                    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    if (bean != null) {
                        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                    }
                }
            }
            mbd.beforeInstantiationResolved = (bean != null);
        }
        return bean;
    }

Synthetic合成

mdb.isSynthetic()表示是否是合成的
有三种合成:合成类,合成方法,合成属性

示例代码
package com.synthetic;
import java.lang.reflect.Method;
public class SyntheticTest {
    public void test(){
        SyntheticTestInner inner = new SyntheticTestInner();
        System.out.println( inner.j );
    }
    class SyntheticTestInner{
        private int j;
                //内部类有私有构造方法 会编译第三个类
                private SyntheticTestInner(){}

    }
    public static void main(String[] args) {
        for (Method method : SyntheticTestInner.class.getDeclaredMethods()) {
            System.out.println(method.getName());
                       //打印access$000  $后面数字是随机的
        }

               int num=1;
        for (Constructor declaredConstructor : SyntheticTestInner.class.getDeclaredConstructors()) {
            for (Parameter parameter : declaredConstructor.getParameters()) {
                System.out.println("第"+num+"构造方法参数"+parameter);
            }
            num++;
        }
             
    }
}
合成方法

内部类属性,会合成一个方法access$000 供外部类访问
class文件形式


Synthetic.png
合成类

内部类有私有构造方法 会编译第三个类(合成类)


合成类.png

spring AOP源码实现分析_第1张图片
构造方法参数打印.png

之后将会执行下面后置处理器方法
AbstractAutoProxyCreator#postProcessBeforeInstantiation

    public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {
        Object cacheKey = getCacheKey(beanClass, beanName);

        if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
            if (this.advisedBeans.containsKey(cacheKey)) {
                return null;
            }
            if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return null;
            }
        }

        // Create proxy here if we have a custom TargetSource.
        // Suppresses unnecessary default instantiation of the target bean:
        // The TargetSource will handle target instances in a custom fashion.
        TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
        if (targetSource != null) {
            if (StringUtils.hasLength(beanName)) {
                this.targetSourcedBeans.add(beanName);
            }
            Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
            Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }

        return null;
    }
advisedBeans存储

advisedBeans存储不需要被代理的bean
1、已经被代理,advisedBeans的值是true
经过cdlib或jdk动态代理生成代理类后,会设置true属性值
2、不能被代理,advisedBeans的值是false
基础类Advice,Pointcut,Advisor,AopInfrastructureBean
加了Advisor注解
isInfrastructureClass方法

    protected boolean isInfrastructureClass(Class beanClass) {
        return (super.isInfrastructureClass(beanClass) ||
                (this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
    }
protected boolean isInfrastructureClass(Class beanClass) {
        boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
                Pointcut.class.isAssignableFrom(beanClass) ||
                Advisor.class.isAssignableFrom(beanClass) ||
                AopInfrastructureBean.class.isAssignableFrom(beanClass);
        if (retVal && logger.isTraceEnabled()) {
            logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
        }
        return retVal;
    }

   public boolean isAspect(Class clazz) {
        return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));
    }

    private boolean hasAspectAnnotation(Class clazz) {
        return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);
    }
    private boolean compiledByAjc(Class clazz) {
        for (Field field : clazz.getDeclaredFields()) {
            if (field.getName().startsWith(AJC_MAGIC)) {
                return true;
            }
        }
        return false;
    }

shouldSkip方法

protected boolean shouldSkip(Class beanClass, String beanName) {
        // TODO: Consider optimization by caching the list of the aspect names
        List candidateAdvisors = findCandidateAdvisors();
        for (Advisor advisor : candidateAdvisors) {
            if (advisor instanceof AspectJPointcutAdvisor &&
                    ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
                return true;
            }
        }
        return super.shouldSkip(beanClass, beanName);
    }

postProcessAfterInitialization

AbstractAutoProxyCreator#postProcessAfterInitialization 是初始化完成之后的后置处理器
调用链先执行wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)方法

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
        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;
        }

        // Create proxy if we have advice.
        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;
    }

getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);匹配Advisors 如果返回null将不会被代理
advisedBeans被设置为false

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) {
                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)) {
                return new JdkDynamicAopProxy(config);
            }
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            return new JdkDynamicAopProxy(config);
        }
    }

proxyTargetClass、optimize、opaque、exposeProxy、frozen默认都是false
设置proxyFactory.setProxyTargetClass(true);有三种情况:
1、是个配置类
2、普通类没有实现接口
3、@EnableAspectJAutoProxy(proxyTargetClass = true)

配置类

如果是配置类,在配置类生成enhance(增强类)时将会添加(ConfigurationClassPostProcessor#enhanceConfigurationClasses)
beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);有这个属性值,将会把proxyTargetClass设置为true
shouldProxyTargetClass(beanClass, beanName)方法

PRESERVE_TARGET_CLASS_ATTRIBUTE =
            Conventions.getQualifiedAttributeName(AutoProxyUtils.class, "preserveTargetClass");
protected boolean shouldProxyTargetClass(Class beanClass, @Nullable String beanName) {
        return (this.beanFactory instanceof ConfigurableListableBeanFactory &&
                AutoProxyUtils.shouldProxyTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName));
    }
public static boolean shouldProxyTargetClass(ConfigurableListableBeanFactory beanFactory, @Nullable String beanName) {
        if (beanName != null && beanFactory.containsBeanDefinition(beanName)) {
            BeanDefinition bd = beanFactory.getBeanDefinition(beanName);
            return Boolean.TRUE.equals(bd.getAttribute(PRESERVE_TARGET_CLASS_ATTRIBUTE));
        }
        return false;
    }
普通类

在evaluateProxyInterfaces(beanClass, proxyFactory);方法
如果是普通类没有实现接口,将会把proxyTargetClass设置为true
如果实现了接口,将会给代理工厂设置实现的接口。直接使用JDK动态代理

protected void evaluateProxyInterfaces(Class beanClass, ProxyFactory proxyFactory) {
        Class[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
        boolean hasReasonableProxyInterface = false;
        for (Class ifc : targetInterfaces) {
            if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) &&
                    ifc.getMethods().length > 0) {
                hasReasonableProxyInterface = true;
                break;
            }
        }
        if (hasReasonableProxyInterface) {
            // Must allow for introductions; can't just set interfaces to the target's interfaces only.
            for (Class ifc : targetInterfaces) {
                proxyFactory.addInterface(ifc);
            }
        }
        else {
            proxyFactory.setProxyTargetClass(true);
        }
    }
public Object getProxy(@Nullable ClassLoader classLoader) {
        return createAopProxy().getProxy(classLoader);
    }

创建代理类

通过AopProxy#getProxy(ClassLoader)创建代理类

JdkDynamicAopProxy#getProxy(java.lang.ClassLoader)
public Object getProxy(@Nullable ClassLoader classLoader) {
        if (logger.isDebugEnabled()) {
            logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
        }
        Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
        findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
        return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
    }
CglibAopProxy#getProxy(java.lang.ClassLoader)
public Object getProxy(@Nullable ClassLoader classLoader) {
        if (logger.isDebugEnabled()) {
            logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
        }

        try {
            Class rootClass = this.advised.getTargetClass();
            Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

            Class proxySuperClass = rootClass;
            if (ClassUtils.isCglibProxyClass(rootClass)) {
                proxySuperClass = rootClass.getSuperclass();
                Class[] additionalInterfaces = rootClass.getInterfaces();
                for (Class additionalInterface : additionalInterfaces) {
                    this.advised.addInterface(additionalInterface);
                }
            }

            // Validate the class, writing log messages as necessary.
            validateClassIfNecessary(proxySuperClass, classLoader);

            // Configure CGLIB Enhancer...
            Enhancer enhancer = createEnhancer();
            if (classLoader != null) {
                enhancer.setClassLoader(classLoader);
                if (classLoader instanceof SmartClassLoader &&
                        ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
                    enhancer.setUseCache(false);
                }
            }
            enhancer.setSuperclass(proxySuperClass);
            enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
            enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
            enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));

            Callback[] callbacks = getCallbacks(rootClass);
            Class[] types = new Class[callbacks.length];
            for (int x = 0; x < types.length; x++) {
                types[x] = callbacks[x].getClass();
            }
            // fixedInterceptorMap only populated at this point, after getCallbacks call above
            enhancer.setCallbackFilter(new ProxyCallbackFilter(
                    this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
            enhancer.setCallbackTypes(types);

            // Generate the proxy class and create a proxy instance.
            return createProxyClassAndInstance(enhancer, callbacks);
        }
        catch (CodeGenerationException | IllegalArgumentException ex) {
            throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
                    ": Common causes of this problem include using a final class or a non-visible class",
                    ex);
        }
        catch (Throwable ex) {
            // TargetSource.getTarget() failed
            throw new AopConfigException("Unexpected AOP exception", ex);
        }
    }

参考

ObjenesisCglibAopProxy

public ObjenesisCglibAopProxy(AdvisedSupport config) {
        super(config);
    }
public CglibAopProxy(AdvisedSupport config) throws AopConfigException {
        Assert.notNull(config, "AdvisedSupport must not be null");
        if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
            throw new AopConfigException("No advisors and no TargetSource specified");
        }
        this.advised = config;
        this.advisedDispatcher = new AdvisedDispatcher(this.advised);
    }

JdkDynamicAopProxy

public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
        Assert.notNull(config, "AdvisedSupport must not be null");
        if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
            throw new AopConfigException("No advisors and no TargetSource specified");
        }
        this.advised = config;
    }

总结

AOP源码分析主要是代理类生成的时机和种类
advisedBeans 存储不需要代理的bean
种类:
1、JdkDynamicAopProxy 实现接口
2、ObjenesisCglibAopProxy
生成时机:
1、AbstractAutoProxyCreator#postProcessAfterInitialization
2、循环依赖的AbstractAutoProxyCreator#getEarlyBeanReference方法

你可能感兴趣的:(spring AOP源码实现分析)