Package com.alibaba.asyncload.impl.spring

Source Code of com.alibaba.asyncload.impl.spring.CompositeAutoProxyCreator

package com.alibaba.asyncload.impl.spring;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.aopalliance.aop.Advice;
import org.springframework.aop.Advisor;
import org.springframework.aop.framework.AopInfrastructureBean;
import org.springframework.aop.framework.ProxyConfig;
import org.springframework.aop.framework.ProxyFactoryBean;
import org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.transaction.interceptor.TransactionProxyFactoryBean;
import org.springframework.util.ClassUtils;
import org.springframework.util.PatternMatchUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;

/**
* 提供一种机制:无侵入的拦截机制,与现有的bean定义进行融合。实现自定义的{@linkplain BeanPostProcessor}进行替换,部分代码copy from
* {@linkplain AbstractAutoProxyCreator}
*
* <pre>
* 融合的规则:
* 1. 原先的bean是{@linkplain ProxyFactoryBean},则将自己的拦截器定义和proxy bean的定义进行融合,<strong>只是会合并原先的拦截器定义,其他的不做融合</strong>
*    可通过applyCommonInterceptorsFirst=true/false指定顺序.如果是false则{@linkplain CompositeAutoProxyCreator}定义的拦截器排在后面
* 2. 如果原先的bean是除{@linkplain ProxyFactoryBean}的bean,则尝试自动创建ProxyFactoryBean,对应的拦截器也仅是所配置的拦截器列表,不会进行自动的扫描和装配
* 3. 其他的类似:{@linkplain TransactionProxyFactoryBean}并不会进行一个融合的处理
*
* </pre>
*
* @author jianghang 2011-4-25 上午10:43:12
*/
public class CompositeAutoProxyCreator extends ProxyConfig implements BeanPostProcessor, Ordered, BeanClassLoaderAware, BeanFactoryAware, AopInfrastructureBean {

    private static final long  serialVersionUID             = 8458055362270662345L;
    private static final Field interceptorNamesField        = ReflectionUtils.findField(ProxyFactoryBean.class,
                                                                                        "interceptorNames");

    private ClassLoader        proxyClassLoader             = ClassUtils.getDefaultClassLoader();
    private boolean            classLoaderConfigured        = false;
    private BeanFactory        beanFactory;
    private List               beanNames;
    private int                order                        = Integer.MAX_VALUE;
    private String[]           interceptorNames             = new String[0];
    private boolean            applyCommonInterceptorsFirst = false;
    private final Set          nonAdvisedBeans              = Collections.synchronizedSet(new HashSet());

    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        // 不做处理
        return bean;
    }

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

        return bean;
    }

    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        if (this.nonAdvisedBeans.contains(cacheKey)) {
            return bean;
        }
        if (isInfrastructureClass(bean.getClass())) {
            this.nonAdvisedBeans.add(cacheKey);
            return bean;
        }
        // 不能进行代理cache,singleton的实现有spring core核心机制来保证,如果是singleton不会回调多次
        // Create proxy if we have advice.
        if (this.beanNames != null) {
            for (Iterator it = this.beanNames.iterator(); it.hasNext();) {
                String mappedName = (String) it.next();
                if (isMatch(beanName, mappedName)) {
                    if (ProxyFactoryBean.class.isAssignableFrom(bean.getClass())) {
                        ProxyFactoryBean proxyFactoryBean = (ProxyFactoryBean) bean;
                        String[] orignInterceptorNames = getInterceptorFromProxyFactoryBean(proxyFactoryBean);
                        String[] newInterceptorNames = new String[orignInterceptorNames.length
                                                                  + interceptorNames.length];
                        if (applyCommonInterceptorsFirst) {// 如果是true,则将Auto-proxy的拦截器定义到最前面
                            // 构造新的的拦截器列表
                            System.arraycopy(interceptorNames, 0, newInterceptorNames, 0, interceptorNames.length);
                            System.arraycopy(orignInterceptorNames, 0, newInterceptorNames, interceptorNames.length,
                                             orignInterceptorNames.length);
                        } else {
                            System.arraycopy(orignInterceptorNames, 0, newInterceptorNames, 0,
                                             orignInterceptorNames.length);
                            System.arraycopy(interceptorNames, 0, newInterceptorNames, orignInterceptorNames.length,
                                             interceptorNames.length);
                        }
                        // 重新设置新的inteceptorNames
                        proxyFactoryBean.setInterceptorNames(newInterceptorNames);
                        return proxyFactoryBean;
                    } else {
                        // 如果是单例,对应的代理bean对象为同一个
                        ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
                        proxyFactoryBean.setBeanFactory(beanFactory);
                        proxyFactoryBean.setBeanClassLoader(proxyClassLoader);
                        proxyFactoryBean.setInterceptorNames(interceptorNames);
                        proxyFactoryBean.copyFrom(this); // 拷贝对应的一些Proxy config
                        proxyFactoryBean.setTarget(bean);
                        return proxyFactoryBean.getObject();
                    }
                }
            }
        }

        this.nonAdvisedBeans.add(cacheKey);
        return bean;
    }

    // =========================== helper method ================================

    private String[] getInterceptorFromProxyFactoryBean(ProxyFactoryBean bean) {
        synchronized (interceptorNamesField) {
            try {
                interceptorNamesField.setAccessible(true);
                try {
                    Object obj = interceptorNamesField.get(bean);
                    return obj != null ? (String[]) obj : new String[0];
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            } finally {
                interceptorNamesField.setAccessible(false);
            }
        }

    }

    /**
     * 对应的内存cache的key
     */
    protected Object getCacheKey(Class beanClass, String beanName) {
        return beanClass.getName() + "_" + beanName;
    }

    /**
     * 不对基础的框架类做auto-proxy
     *
     * @param beanClass
     * @return
     */
    protected boolean isInfrastructureClass(Class beanClass) {
        return Advisor.class.isAssignableFrom(beanClass) || Advice.class.isAssignableFrom(beanClass)
               || AopInfrastructureBean.class.isAssignableFrom(beanClass);
    }

    /**
     * 返回是否匹配,支持简单的通配符: "xxx*", "*xxx" "*xxx*"
     */
    protected boolean isMatch(String beanName, String mappedName) {
        return PatternMatchUtils.simpleMatch(mappedName, beanName);
    }

    // ========================= setter / getter ===========================

    public final void setOrder(int order) {
        this.order = order;
    }

    public final int getOrder() {
        return this.order;
    }

    public void setInterceptorNames(String[] interceptorNames) {
        this.interceptorNames = interceptorNames;
    }

    public void setApplyCommonInterceptorsFirst(boolean applyCommonInterceptorsFirst) {
        this.applyCommonInterceptorsFirst = applyCommonInterceptorsFirst;
    }

    public void setBeanClassLoader(ClassLoader classLoader) {
        if (!this.classLoaderConfigured) {
            this.proxyClassLoader = classLoader;
        }
    }

    public void setBeanFactory(BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }

    public void setBeanNames(String[] beanNames) {
        this.beanNames = new ArrayList(beanNames.length);
        for (int i = 0; i < beanNames.length; i++) {
            this.beanNames.add(StringUtils.trimWhitespace(beanNames[i]));
        }
    }

}
TOP

Related Classes of com.alibaba.asyncload.impl.spring.CompositeAutoProxyCreator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.