Back to Javatutorial

AnnotationAwareAspectJAutoProxyCreator分析(下)

docs/Spring全家桶/Spring源码分析/SpringAOP/AnnotationAwareAspectJAutoProxyCreator分析(下).md

1.0.018.5 KB
Original Source

һƪҪ AbstractAutoProxyCreator#postProcessAfterInitialization AbstractAutoProxyCreator#postProcessAfterInitialization

ĵ

|-AnnotationConfigApplicationContext
 |-AbstractApplicationContext#refresh
  |-AbstractApplicationContext#finishBeanFactoryInitialization
   |-ConfigurableListableBeanFactory#preInstantiateSingletons
    |-AbstractBeanFactory#getBean(String)
     |-AbstractBeanFactory#doGetBean
      |-DefaultSingletonBeanRegistry#getSingleton(String, ObjectFactory<?>)
       |-ObjectFactory#getObject
        |-AbstractBeanFactory#createBean
         |-AbstractAutowireCapableBeanFactory#doCreateBean
          |-AbstractAutowireCapableBeanFactory#initializeBean(String, Object, RootBeanDefinition)
           |-AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
            |-AbstractAutoProxyCreator#postProcessAfterInitialization

ʵĵ spring bean Ĵ̣ǽ AbstractAutoProxyCreator#postProcessAfterInitialization

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

AbstractAutoProxyCreator#wrapIfNecessary

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

е㳤붼жϣ aop ܹϵйϵĴֻУ

// Ҫһ
// 1\. isInfrastructureClassжϵǰǷΪaop࣬
//    Advice/Pointcut/Advisorȵ࣬Ƿ @AspectJע
// 2\. shouldSkip࣬жǷų
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
    ...
}

// ҪУǷӦñȡǿ
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);

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

ҪһһƪѾҪҪ``Ҫ

1. ȡǿ

AbstractAdvisorAutoProxyCreator

@Override
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(
        Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
    // ҷǿ¿
    List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
    if (advisors.isEmpty()) {
        return DO_NOT_PROXY;
    }
    return advisors.toArray();
}

/**
 * ҷǿ
 */
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    //ȡеǿһƪѾ
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
    //֤beanClassǷñӦã򷵻beanǿ
    List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
    extendAdvisors(eligibleAdvisors);
    if (!eligibleAdvisors.isEmpty()) {
        eligibleAdvisors = sortAdvisors(eligibleAdvisors);
    }
    return eligibleAdvisors;
}

/**
 * ֤beanClassǷñ
 */
protected List<Advisor> findAdvisorsThatCanApply(
        List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
    ProxyCreationContext.setCurrentProxiedBeanName(beanName);
    try {
        // ֤beanClassǷñ
        return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
    }
    finally {
        ProxyCreationContext.setCurrentProxiedBeanName(null);
    }
}

spring ķñȽһ·׷٣յ AopUtils.findAdvisorsThatCanApply ¿

AopUtils

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
    if (candidateAdvisors.isEmpty()) {
        return candidateAdvisors;
    }
    List<Advisor> eligibleAdvisors = new ArrayList<>();
    //  candidateAdvisorsжǷ
    for (Advisor candidate : candidateAdvisors) {
        //ǿص㣬¿
        if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
            eligibleAdvisors.add(candidate);
        }
    }
    boolean hasIntroductions = !eligibleAdvisors.isEmpty();
    for (Advisor candidate : candidateAdvisors) {
        if (candidate instanceof IntroductionAdvisor) {
            // already processed
            continue;
        }
        //ͨbeanĴ
        if (canApply(candidate, clazz, hasIntroductions)) {
            eligibleAdvisors.add(candidate);
        }
    }
    return eligibleAdvisors;
}

/**
 * жǷҪǿ
 */
public static boolean canApply(Advisor advisor, Class<?> targetClass) {
    // һ
    return canApply(advisor, targetClass, false);
}

/**
 * жǷҪǿ
 */
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
    //ų
    if (advisor instanceof IntroductionAdvisor) {
        return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
    }
    else if (advisor instanceof PointcutAdvisor) {
        PointcutAdvisor pca = (PointcutAdvisor) advisor;
        //÷
        return canApply(pca.getPointcut(), targetClass, hasIntroductions);
    }
    else {
        // It doesn't have a pointcut so we assume it applies.
        return true;
    }
}

/**
 * жǷҪǿ
 */
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
    Assert.notNull(pc, "Pointcut must not be null");
    //еǷų
    if (!pc.getClassFilter().matches(targetClass)) {
        return false;
    }
    //֤עǷڷ
    MethodMatcher methodMatcher = pc.getMethodMatcher();
    if (methodMatcher == MethodMatcher.TRUE) {
        // No need to iterate the methods if we're matching any method anyway...
        return true;
    }

    IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
    if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
        introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
    }

    // classestargetClassObjectиࡢнӿ
    Set<Class<?>> classes = new LinkedHashSet<>();
    if (!Proxy.isProxyClass(targetClass)) {
        classes.add(ClassUtils.getUserClass(targetClass));
    }
    classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));

    // ѭжϷǷҪ
    // Կ
    // 1\. ֻҪһҪôͻᱻ
    // 2\. зҪôҲᱻ
    for (Class<?> clazz : classes) {
         // ȡ clazz ķ
         // ǰķObjectи෽ӿڵĬϷ
        Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
        for (Method method : methods) {
            //ȡʵֵнӿں㼶ķѭ֤
            if (introductionAwareMethodMatcher != null ?
                introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
                methodMatcher.matches(method, targetClass)) {
                return true;
            }
        }
    }

    return false;
}

Ͼ˽ spring жһǷҪģܽ£

  1. ȡĿе󣬽е淽װΪһ List<Advisor>һƪϸ
  2. Advisorÿһ Advisor÷ȡǰij Object и༰ӿڣΪ Set<Class>
  3. Set<Class>ÿһ Class÷ȡ Class Object иķӿڵĬϷΪ Method[];
  4. Method[]һ method Advisor ʾǰ Advisor Ӧõǰ bean bean ҪһյõĽҲһ List<Advisor>ʾж Advisor ҪӦõö

αڣ

// 1\. ȡеAdvisor
List<Advisor> advisorList = getAdvisorList();
// 2\. Advisor
for(Advisor advisor : advisorList) {
    // ȡǰij`Object`и༰ӿڣclassSetҲtargetClass
    Set<Class> classSet = getSuperClassAndInterfaces(targetClass);
    for(Class cls : classSet) {
        // clsжķǰķObjectи෽ӿڵĬϷ
        Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
        //  Щ
        for (Method method : methods) {
             // жmethodǷ
        }
    }
}

õ List<Advisor> 󣬽Ǹ List<Advisor> ˡ

2.

spring ̡

AbstractAutoProxyCreator#wrapIfNecessary

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    ...
    if (specificInterceptors != DO_NOT_PROXY) {
        this.advisedBeans.put(cacheKey, Boolean.TRUE);
        // ﴴ
        // - specificInterceptorsӦõö  Advisor
        //    specificInterceptorsĻȡ̣һѾϸˣ׸
        // - SingletonTargetSourceԭʼһװ
        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;
}

SingletonTargetSource

public class SingletonTargetSource implements TargetSource, Serializable {

    private static final long serialVersionUID = 9031246629662423738L;

    private final Object target;

    public SingletonTargetSource(Object target) {
        Assert.notNull(target, "Target object must not be null");
        this.target = target;
    }

    @Override
    public Class<?> getTargetClass() {
        return this.target.getClass();
    }

    @Override
    public Object getTarget() {
        return this.target;
    }

    ...
}

ܼ򵥣Ƕԭʼһװ¿

AbstractAutoProxyCreator#createProxy

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();
    //ʹproxyFactorycopyǰе
    proxyFactory.copyFrom(this);

    // жǷʹCglib̬עָ
    // @EnableAspectJAutoProxy(proxyTargetClass = true)
    if (!proxyFactory.isProxyTargetClass()) {
        //  beanFactory  ConfigurableListableBeanFactory
        //  BeanDefinition ԣijһʹ cglib 
        if (shouldProxyTargetClass(beanClass, beanName)) {
            proxyFactory.setProxyTargetClass(true);
        }
        else {
            // ûÿ, жbeanǷкʵĽӿʹJDKĶ̬
            // ע⣺JDK̬Ǵнӿڵ
            // ûʵκνӿֻʹCglib̬
            evaluateProxyInterfaces(beanClass, proxyFactory);
        }
    }

    // Advisor
    // 1\. ӹ Interceptor
    // 2\. ڸadvisorжͣȻתΪ
    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    //ǿ
    proxyFactory.addAdvisors(advisors);
    //Ҫ
    proxyFactory.setTargetSource(targetSource);
    //Springһչ㣬ĬʵΪաҪԴʱʵ
    customizeProxyFactory(proxyFactory);

    proxyFactory.setFrozen(this.freezeProxy);
    if (advisorsPreFiltered()) {
        proxyFactory.setPreFiltered(true);
    }
    //ʹôȡ
    return proxyFactory.getProxy(getProxyClassLoader());
}

@EnableAspectJAutoProxy עУʹ proxyTargetClass = true Ŀʹ cglib ڴҲ֣

// ֻproxyFactory.isProxyTargetClass()ΪfalseʱŻж
// ֮ @EnableAspectJAutoProxy(proxyTargetClass = true) ʱ
// ĴDzеģĬʹþcglib
if (!proxyFactory.isProxyTargetClass()) {
    // жû BeanDefinition ʹ cglib
    if (shouldProxyTargetClass(beanClass, beanName)) {
        proxyFactory.setProxyTargetClass(true);
    }
    else {
        // ǷӿڵǷjdk̬
        evaluateProxyInterfaces(beanClass, proxyFactory);
    }
}

spring жһǷ jdk ̬أ֪˵ʵ˽ӿڣͿʹöֻ̬ʹ cglib spring жϵģ

ProxyProcessorSupport#evaluateProxyInterfaces

/**
 * жǷʹjdk̬
 */
protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {
    // ȡнӿ
    Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
    boolean hasReasonableProxyInterface = false;
    for (Class<?> ifc : targetInterfaces) {
        // 1.isConfigurationCallbackInterface: жifcǷΪInitializingBeanDisposableBean
        //   CloseableAutoCloseableԼ Aware
        // 2.isInternalLanguageInterface: ǷΪڲԽӿڣgroovymock
        // 3.ifc.getMethods().length > 0ӿڵķ1
        if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) &&
                ifc.getMethods().length > 0) {
            hasReasonableProxyInterface = true;
            break;
        }
    }
    if (hasReasonableProxyInterface) {
         // ҪеĽӿڶõproxyFactory
         // һ£һA ʵ˽ӿ I1  I2
         // AĶa  йܵspringôʹ beanFactory.get(I1.class)
         //  beanFactory.get(I1.class)Ӧܻȡa.
         for (Class<?> ifc : targetInterfaces) {
             proxyFactory.addInterface(ifc);
         }
    }
    else {
        proxyFactory.setProxyTargetClass(true);
    }
}

Դspring жǷʹ jdk ̬Ĺ֪ϵIJ࣬ʵӿھʹ jdk ̬spring ų InitializingBean``DisposableBean``Closeable``AutoCloseable ȽӿڣͬʱҲųκηĽӿڡ

spring жǷʹ jdk ̬󣬽ӿ spring δġΪ˵⣬ȼ AbstractAutoProxyCreator#createProxy

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
        @Nullable Object[] specificInterceptors, TargetSource targetSource) {
    // ʡһЩ
    ...
    ProxyFactory proxyFactory = new ProxyFactory();
    //ʹproxyFactorycopyǰе
    proxyFactory.copyFrom(this);
    // ʡ˺öж
    proxyFactory.setProxyTargetClass(true);
    //ǿ
    proxyFactory.addAdvisors(advisors);
    //Ҫ
    proxyFactory.setTargetSource(targetSource);
    ...
    //ʹôȡ
    return proxyFactory.getProxy(getProxyClassLoader());
}

Կһ ProxyFactory ȻöһЩֵ¿

ProxyFactory#getProxy(java.lang.ClassLoader)

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

createAopProxy() getProxy(classLoader) createAopProxy()

ProxyCreatorSupport#createAopProxy

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

DefaultAopProxyFactory#createAopProxy

/**
 * жϴ
 * ʹjdk̬ͷ JdkDynamicAopProxy
 * ͷ ObjenesisCglibAopProxy
 */
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
        Class<?> targetClass = config.getTargetClass();
        if (targetClass == null) {
            throw new AopConfigException(...);
        }
        if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
            return new JdkDynamicAopProxy(config);
        }
        return new ObjenesisCglibAopProxy(config);
    }
    else {
        return new JdkDynamicAopProxy(config);
    }
}

ǾףJdkDynamicAopProxy jdk ̬ģObjenesisCglibAopProxy cglib ġ getProxy(classLoader)

JdkDynamicAopProxy#getProxy(java.lang.ClassLoader)

@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
    Class<?>[] proxiedInterfaces = AopProxyUtils
            .completeProxiedInterfaces(this.advised, true);
    // Ƿequals()hashCode()
    findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
    //  jdk  
    return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

õĴʲôģ

Կ h Աľ JdkDynamicAopProxy JdkDynamicAopProxy advised Ա˴ĴϢ

CglibAopProxy#getProxy(java.lang.ClassLoader)

public Object getProxy(@Nullable ClassLoader classLoader) {
    try {
        Class<?> rootClass = this.advised.getTargetClass();
        Assert.state(rootClass != null, "xxx");

        Class<?> proxySuperClass = rootClass;
        if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
            proxySuperClass = rootClass.getSuperclass();
            Class<?>[] additionalInterfaces = rootClass.getInterfaces();
            for (Class<?> additionalInterface : additionalInterfaces) {
                this.advised.addInterface(additionalInterface);
            }
        }

        validateClassIfNecessary(proxySuperClass, classLoader);

        //  Enhancer 󣬲setһЩ
        Enhancer enhancer = createEnhancer();
        if (classLoader != null) {
            enhancer.setClassLoader(classLoader);
            if (classLoader instanceof SmartClassLoader &&
                    ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
                enhancer.setUseCache(false);
            }
        }
        // SuperclassҪ
        enhancer.setSuperclass(proxySuperClass);
        // ýӿڣ SpringProxyAdvised
        enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
        enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
        enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));

        Callback[] callbacks = getCallbacks(rootClass);
        Class<?>[] types = new Class<?>[callbacks.length];
        for (int x = 0; x < types.length; x++) {
            types[x] = callbacks[x].getClass();
        }
        enhancer.setCallbackFilter(new ProxyCallbackFilter(
                this.advised.getConfigurationOnlyCopy(), 
                this.fixedInterceptorMap, this.fixedInterceptorOffset));
        enhancer.setCallbackTypes(types);

        return createProxyClassAndInstance(enhancer, callbacks);
    }
    catch (CodeGenerationException | IllegalArgumentException ex) {
        throw new AopConfigException(...);
    }
    catch (Throwable ex) {
        throw new AopConfigException("Unexpected AOP exception", ex);
    }
}

spring ʹ cglib Ҫõ Enhancer ࣬һٷ

ҲõĶ

3. ܽ

Ҫ AbstractAutoProxyCreator#postProcessAfterInitialization÷Ҫ£

  1. ȡĿ࣬е㷽װΪ ListʵϣһIJҲ AbstractAutoProxyCreator#postProcessBeforeInitialization ִУȻ󽫽һʵֱڻý
  2. ȡǰǿһжЩǿڵǰжʱȻȡǰнӿ벻 Object ĸ࣬ȻһжЩӿеķǷǿֻҪһ㣬ͱʾǰҪ
  3. 󣺴ʱĬ£Ƿʵ˽ӿѡʹ jdk ̬ cglibӦڵǰ bean List ҲװС

ԭӣhttps://my.oschina.net/funcy/blog/4687961 ߸ˮƽд֮ӭָԭףҵתϵ߻Ȩҵתע