spring AOP源碼分析(二)


現在,我們將對代理對象的生成過程進行分析。

spring AOP源碼分析(一)的例子中,將會生成哪些對象呢?

可以看到將會生成六個對象,對應的beanName分別是:

userDao:目標對象

logger:定義的切面

InternalAutoProxyCreator:用來生成代理對象的后置處理器,它實現了BeanPostProcessor,類型是AspectJAwareAdvisorAutoProxyCreator

AspectJPointcutAdvisor#0:定義的通知

AspectJPointcutAdvisor#1:定義的通知

updateUserMethod:切入點表達式

這里我們只要搞明白AspectJAwareAdvisorAutoProxyCreator和userDao這兩個對象的生成過程,那么關於代理對象是如何生成的,也就清楚了。

一.AspectJAwareAdvisorAutoProxyCreator的實例化

AspectJAwareAdvisorAutoProxyCreator是一個后置處理器,它的作用是在bean對象實例化的前后可以進行一些操作。在這里,准確的說是在它的postProcessAfterInitialization方法中完成了對userDao目標對象生成了代理對象,這個方法是代理對象生成的地方,稍后再分析這個方法。現在需要思考的是對於AspectJAwareAdvisorAutoProxyCreator這個對象是什么時候生成的呢?其實它在registerBeanPostProcessors注冊后置處理器的時候實例化的。進入refesh方法

public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);

            try {
                // Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);

                // Register bean processors that intercept bean creation.
          //進入這個方法  registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }

進入registerBeanPostProcessors方法,然后可以追蹤到以下方法

    public static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
     
//獲取所有的后置處理器  String[] postProcessorNames
= beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); // Register BeanPostProcessorChecker that logs an info message when // a bean is created during BeanPostProcessor instantiation, i.e. when // a bean is not eligible for getting processed by all BeanPostProcessors. int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
//對這些后置處理器進行分類存儲
// Separate between BeanPostProcessors that implement PriorityOrdered, // Ordered, and the rest. List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>(); List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>(); List<String> orderedPostProcessorNames = new ArrayList<String>(); List<String> nonOrderedPostProcessorNames = new ArrayList<String>(); for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); priorityOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } }
//以下這些就是針對不同類型的后置處理器分別進行注冊實例化
// First, register the BeanPostProcessors that implement PriorityOrdered. sortPostProcessors(priorityOrderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); // Next, register the BeanPostProcessors that implement Ordered. List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>(); for (String ppName : orderedPostProcessorNames) { //AspectJAwareAdvisorAutoProxyCreator的實例化就是在這里進行的
BeanPostProcessor pp
= beanFactory.getBean(ppName, BeanPostProcessor.class); orderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } sortPostProcessors(orderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, orderedPostProcessors); // Now, register all regular BeanPostProcessors. List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>(); for (String ppName : nonOrderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); nonOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); // Finally, re-register all internal BeanPostProcessors. sortPostProcessors(internalPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, internalPostProcessors); // Re-register post-processor for detecting inner beans as ApplicationListeners, // moving it to the end of the processor chain (for picking up proxies etc). beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); }

現在AspectJAwareAdvisorAutoProxyCreator對象已生成,那么對於其它bean實例化的時候它就可以起到后置處理器應有的作用了。

二.userDao的實例化過程

目標對象userDao的實例化過程,也包含了代理對象的生成過程,通過源碼來一步步分析。

進入AbstractAutowireCapableBeanFactory類的initializeBean方法

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(new PrivilegedAction<Object>() {
                @Override
                public Object run() {
                    invokeAwareMethods(beanName, bean);
                    return null;
                }
            }, getAccessControlContext());
        }
        else {
            invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
//對該bean調用所有后置處理器的postProcessBeforeInitialization方法 wrappedBean
= applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try {
//調用初始化方法 invokeInitMethods(beanName, wrappedBean, mbd); }
catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) {
//代理對象的生成在這個方法中進行的 wrappedBean
= applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }

進入applyBeanPostProcessorsAfterInitialization方法

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

        Object result = existingBean;
        for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
//獲取所有的后置處理器對該bean進行操作 然后進入AbstractAutoProxyCreator的
//postProcessAfterInitialization方法中 result
= beanProcessor.postProcessAfterInitialization(result, beanName); if (result == null) { return result; } } return result; }
進入AbstractAutoProxyCreator類的postProcessAfterInitialization方法中
    public Object postProcessAfterInitialization(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; }

進入wrapIfNecessary方法

    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        if (beanName != null && 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.
     // 為目標bean查找匹配的通知器 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE);
//如果通知器的數組
specificInterceptors不為空,那么生成代理對象
            Object proxy = createProxy(
                    bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
            this.proxyTypes.put(cacheKey, proxy.getClass());
//把生成的代理對象放到容器中,此時beanName對應的對象不再是目標對象,而是代理對象。
return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; }

接下來我們去分析兩個方法:為目標bean查詢匹配的通知器getAdvicesAndAdvisorsForBean和代理對象的生成方法createProxy

1.查詢匹配的通知器,進入getAdvicesAndAdvisorsForBean方法

protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
//進入該方法 List
<Advisor> advisors = findEligibleAdvisors(beanClass, beanName); if (advisors.isEmpty()) { return DO_NOT_PROXY; } return advisors.toArray(); }

進入getAdvicesAndAdvisorsForBean方法

    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//查找所有的通知器 List
<Advisor> candidateAdvisors = findCandidateAdvisors();
//然后篩選匹配出可應用在beanClass上的通知器 List
<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }

2.代理對象的生成過程,有JDK動態代理和cglib兩種生成方式,默認是JDK動態代理

 進入createProxy方法,這個方法是代理對象生成的地方

/**
     * Create an AOP proxy for the given bean.
     * @param beanClass the class of the bean
     * @param beanName the name of the bean
     * @param specificInterceptors the set of interceptors that is
     * specific to this bean (may be empty, but not null)
     * @param targetSource the TargetSource for the proxy,
     * already pre-configured to access the bean
     * @return the AOP proxy for the bean
     * @see #buildAdvisors
     */
    protected Object createProxy(
            Class<?> beanClass, String beanName, 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);
            }
        }
        // 獲取所有的通知器,並給ProxyFactory配置通知器,目標對象
        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
        proxyFactory.addAdvisors(advisors); // 當調用目標方法時,這些配置好的通知器就會起作用
        proxyFactory.setTargetSource(targetSource);
        customizeProxyFactory(proxyFactory);

        proxyFactory.setFrozen(this.freezeProxy);
        if (advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }
       // 此處生成代理對象,進入ProxyFactory的getProxy方法 return proxyFactory.getProxy(getProxyClassLoader());
    }

進入getProxy方法,由於ProxyFactory繼承ProxyCreatorSupport類,所以進入該方法后可知,真正的實現在ProxyCreatorSupport類中,調用的方法是ProxyCreatorSupport類中的方法,而ProxyFactory只是做了一層封裝。

    /**
     * Create a new proxy according to the settings in this factory.
     * <p>Can be called repeatedly. Effect will vary if we've added
     * or removed interfaces. Can add and remove interceptors.
     * <p>Uses the given class loader (if necessary for proxy creation).
     * @param classLoader the class loader to create the proxy with
     * (or {@code null} for the low-level proxy facility's default)
     * @return the proxy object
     */
    public Object getProxy(ClassLoader classLoader) {
// 下面的createAopProxy()方法是ProxyCreatorSupport類中的方法
return createAopProxy().getProxy(classLoader); }

好了,接下來是重點部分 :

createAopProxy()方法返回的是AopProxy接口類型,它有兩個實現類分別是CglibAopProxy(通過cglib方式生成代理對象)和JdkDynamicAopProxy(通過JDK動態代理方式生成對象),AopProxy的作用是用於生成代理對象的,稍后將會分析這兩種不同的實現方式。

那么,CglibAopProxy或者JdkDynamicAopProxy又是如何生成的呢?進入createAopProxy方法,該方法就是獲取AopProxy的地方,由方法可知,這里使用了AopProxyFactory來創建AopProxy,而AopProxyFactory使用的是DefaultAopProxyFactory類。

    /**
     * Subclasses should call this to get a new AOP proxy. They should <b>not</b>
     * create an AOP proxy with {@code this} as an argument.
     */
    protected final synchronized AopProxy createAopProxy() {
        if (!this.active) {
            activate();
        }
        return getAopProxyFactory().createAopProxy(this);
    }

進入DefaultAopProxyFactory類的createAopProxy方法:

    @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.");
            }
// 如果targetClass是接口類,那么使用JDK來生成代理對象,返回JdkDynamicAopProxy類型的對象
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); }
// 否則,返回ObjenesisCglibAopProxy類型的對象,它是使用cglib的方式生成代理對象的
return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } }

到這里,我們已經清楚AopProxy是如何生成的了,那么接下來我們介紹CglibAopProxy和JdkDynamicAopProxy又是如何生成代理對象的?

JDK動態代理的方式生成代理對象,進入JdkDynamicAopProxy的getProxy方法

    @Override
    public Object getProxy(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);
// 使用JDK的Proxy類來生成代理對象
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); }

cglib的方式生成代理對象,進入CglibAopProxy類的getProxy方法:

@Override
    public Object getProxy(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);
// 創建並配置Enhancer,它是cglib主要的操作類,用於代理對象的生成
// Configure CGLIB Enhancer... Enhancer enhancer = createEnhancer(); if (classLoader != null) { enhancer.setClassLoader(classLoader); if (classLoader instanceof SmartClassLoader && ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) { enhancer.setUseCache(false); } }
// 配置enhancer對象,比如 代理接口,父類,回調方法等 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); // 通過enhancer來生成代理對象 // Generate the proxy class and create a proxy instance. return createProxyClassAndInstance(enhancer, callbacks); } catch (CodeGenerationException 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 (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); } }

好了,現在代理對象已經生成,並且已經設置好了攔截器(通知),當代理對象調用目標方法時,就會觸發這些攔截器,在下一篇文章中我們就介紹,當調用目標方法時,攔截器(通知)是如何起作用的,整個過程是怎樣的。

《springAOP源碼分析一》

《springAOP源碼分析三》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM