content: 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.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());
  
  	@Override
  	public Object postProcessBeforeInitialization(Object bean, String beanName) {
  		// 不做处理
  		return bean;
  	}
  
  	@Override
  	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 (nonAdvisedBeans.contains(cacheKey)) {
  			return bean;
  		}
  		if (isInfrastructureClass(bean.getClass())) {
  			nonAdvisedBeans.add(cacheKey);
  			return bean;
  		}
  		// 不能进行代理cache，singleton的实现有spring core核心机制来保证，如果是singleton不会回调多次
  		// Create proxy if we have advice.
  		if (beanNames != null) {
  			for (Iterator it = 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();
  					}
  				}
  			}
  		}
  
  		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;
  	}
  
  	@Override
  	public final int getOrder() {
  		return order;
  	}
  
  	public void setInterceptorNames(String[] interceptorNames) {
  		this.interceptorNames = interceptorNames;
  	}
  
  	public void setApplyCommonInterceptorsFirst(boolean applyCommonInterceptorsFirst) {
  		this.applyCommonInterceptorsFirst = applyCommonInterceptorsFirst;
  	}
  
  	@Override
  	public void setBeanClassLoader(ClassLoader classLoader) {
  		if (!classLoaderConfigured) {
  			proxyClassLoader = classLoader;
  		}
  	}
  
  	@Override
  	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]));
  		}
  	}
  
  }
  