Spring源码解析之ProxyFactoryBean

这一节我们进入Spring的AOP功能的源码解析。
一:首先我们来看一下ProxyFactoryBean的继承层次
Object
----ProxyConfig
    ----AdvisedSupport
          ----ProxyCreatorSupport
                ----ProxyFactoryBean
在这里,ProxyConfig是一个数据类,这个数据基类为像ProxyFactoryBean这样的子类提供了配置属性。
                AdvisedSupport封装了AOP中对通知和通知器的相关操作。
                ProxyCreatorSupport是子类创建AOP代理对象的一个辅助类

二:ProxyFactoryBean的getObject
/**
  * Return a proxy. Invoked when clients obtain beans from this factory bean.
  * Create an instance of the AOP proxy to be returned by this factory.
  * The instance will be cached for a singleton, and create on each call to
  * <code>getObject()</code> for a proxy.
  * @return a fresh AOP proxy reflecting the current state of this factory
  */
 public Object getObject() throws BeansException {
  initializeAdvisorChain();
  if (isSingleton()) {
   return getSingletonInstance();
  }
  else {
   if (this.targetName == null) {
    logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " +
      "Enable prototype proxies by setting the 'targetName' property.");
   }
   return newPrototypeInstance();
  }
 }
为Proxy代理对象配置Advisor链是在initializeAdvisorChain方法中实现的。
我们来看看initializeAdvisorChain的源码实现:
/**
  * Create the advisor (interceptor) chain. Aadvisors that are sourced
  * from a BeanFactory will be refreshed each time a new prototype instance
  * is added. Interceptors added programmatically through the factory API
  * are unaffected by such changes.
  */
 private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
  if (this.advisorChainInitialized) {
   return;
  }

  if (!ObjectUtils.isEmpty(this.interceptorNames)) {
   if (this.beanFactory == null) {
    throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
      "- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));
   }

   // Globals can't be last unless we specified a targetSource using the property...
   if (this.interceptorNames[this.interceptorNames.length - 1].endsWith(GLOBAL_SUFFIX) &&
     this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) {
    throw new AopConfigException("Target required after globals");
   }

   // Materialize interceptor chain from bean names.
   for (String name : this.interceptorNames) {
    if (logger.isTraceEnabled()) {
     logger.trace("Configuring advisor or advice '" + name + "'");
    }

    if (name.endsWith(GLOBAL_SUFFIX)) {
     if (!(this.beanFactory instanceof ListableBeanFactory)) {
      throw new AopConfigException(
        "Can only use global advisors or interceptors with a ListableBeanFactory");
     }
     addGlobalAdvisor((ListableBeanFactory) this.beanFactory,
       name.substring(0, name.length() - GLOBAL_SUFFIX.length()));
    }

    else {
     // If we get here, we need to add a named interceptor.
     // We must check if it's a singleton or prototype.
     Object advice;
     if (this.singleton || this.beanFactory.isSingleton(name)) {
      // Add the real Advisor/Advice to the chain.
      advice = this.beanFactory.getBean(name);
     }
     else {
      // It's a prototype Advice or Advisor: replace with a prototype.
      // Avoid unnecessary creation of prototype bean just for advisor chain initialization.
      advice = new PrototypePlaceholderAdvisor(name);
     }
     addAdvisorOnChainCreation(advice, name);
    }
   }
  }

  this.advisorChainInitialized = true;
 }
在这个方法中,最核心的操作是addGlobalAdvisor和addAdvisorOnChainCreation,我们来看一下addAdvisorOnChainCreation的源码
/**
  * Invoked when advice chain is created.
  * <p>Add the given advice, advisor or object to the interceptor list.
  * Because of these three possibilities, we can't type the signature
  * more strongly.
  * @param next advice, advisor or target object
  * @param name bean name from which we obtained this object in our owning
  * bean factory
  */
 private void addAdvisorOnChainCreation(Object next, String name) {
  // We need to convert to an Advisor if necessary so that our source reference
  // matches what we find from superclass interceptors.
  Advisor advisor = namedBeanToAdvisor(next);
  if (logger.isTraceEnabled()) {
   logger.trace("Adding advisor with name '" + name + "'");
  }   
  addAdvisor(advisor);
 }
在这里addAdvisor实际上是在父类AdvisorSupport里实现的,是把实例化的Advisor加入到AdvisorSupport的实例变量advisors(LinkedList)中。
现在我们回到ProxyFactoryBean的getObject中,来看一下getSingletonInstance的源码实现。
/**
  * Return the singleton instance of this class's proxy object,
  * lazily creating it if it hasn't been created already.
  * @return the shared singleton proxy
  */
 private synchronized Object getSingletonInstance() {
  if (this.singletonInstance == null) {
   this.targetSource = freshTargetSource();
   if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
    // Rely on AOP infrastructure to tell us what interfaces to proxy.
    Class targetClass = getTargetClass();
    if (targetClass == null) {
     throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
    }
    setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
   }
   // Initialize the shared singleton instance.
   super.setFrozen(this.freezeProxy);
   this.singletonInstance = getProxy(createAopProxy());
  }
  return this.singletonInstance;
 }
我们可以看到属性singletonInstance用来缓存这个单件对象,具体的获取是通过getProxy(createAopProxy())方法来完成的。
/**
  * Return the proxy object to expose.
  * <p>The default implementation uses a <code>getProxy</code> call with
  * the factory's bean class loader. Can be overridden to specify a
  * custom class loader.
  * @param aopProxy the prepared AopProxy instance to get the proxy from
  * @return the proxy object to expose
  * @see AopProxy#getProxy(ClassLoader)
  */
 protected Object getProxy(AopProxy aopProxy) {
  return aopProxy.getProxy(this.proxyClassLoader);
 }
我们首先来看一下createAopProxy方法的源码,这个方法是在父类ProxyCreatorSupport中实现的。
/**
  * Subclasses should call this to get a new AOP proxy. They should <b>not</b>
  * create an AOP proxy with <code>this</code> as an argument.
  */
 protected final synchronized AopProxy createAopProxy() {
  if (!this.active) {
   activate();
  }
  return getAopProxyFactory().createAopProxy(this);
 }
getAopProxyFactory()方法返回的DefaultAopProxyFactory,我们来看看DefaultAopProxyFactory是如何createAopProxy的。
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()) {
    return new JdkDynamicAopProxy(config);
   }
   if (!cglibAvailable) {
    throw new AopConfigException(
      "Cannot proxy target class because CGLIB2 is not available. " +
      "Add CGLIB to the class path or specify proxy interfaces.");
   }
   return CglibProxyFactory.createCglibProxy(config);
  }
  else {
   return new JdkDynamicAopProxy(config);
  }
 }
根据源码我们可以看出DefaultAopProxyFactory根据不同的需要生成JdkDynamicAopProxy或者Cglib2AopProxy.现在我们来看看JdkDynamicAopProxy是怎样完成AopProxy代理对象生成工作的。
JdkDynamicAopProxy生成Proxy代理对象源码:
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);
  findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
  return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
 }
重点关注Proxy.newProxyInstance这个代理方法,通过this我们知道JdkDynamicAopProxy implements InvocationHandler,对于invoke方法的源码留待下一节讲解。
我们现来看一下Cglib2AopProxy是如何getProxy的。
public Object getProxy(ClassLoader classLoader) {
  if (logger.isDebugEnabled()) {
   logger.debug("Creating CGLIB2 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 (AopUtils.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);

   // 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.setStrategy(new UndeclaredThrowableStrategy(UndeclaredThrowableException.class));
   enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
   enhancer.setInterceptDuringConstruction(false);

   Callback[] callbacks = getCallbacks(rootClass);
   enhancer.setCallbacks(callbacks);
   enhancer.setCallbackFilter(new ProxyCallbackFilter(
     this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));

   Class[] types = new Class[callbacks.length];
   for (int x = 0; x < types.length; x++) {
    types[x] = callbacks[x].getClass();
   }
   enhancer.setCallbackTypes(types);

   // Generate the proxy class and create a proxy instance.
   Object proxy;
   if (this.constructorArgs != null) {
    proxy = enhancer.create(this.constructorArgTypes, this.constructorArgs);
   }
   else {
    proxy = enhancer.create();
   }

   return proxy;
  }
  catch (CodeGenerationException ex) {
   throw new AopConfigException("Could not generate CGLIB subclass of class [" +
     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 class [" +
     this.advised.getTargetClass() + "]: " +
     "Common causes of this problem include using a final class or a non-visible class",
     ex);
  }
  catch (Exception ex) {
   // TargetSource.getTarget() failed
   throw new AopConfigException("Unexpected AOP exception", ex);
  }
 }
我们进入getCallbacks方法来看看是如何生成callback的 
private Callback[] getCallbacks(Class rootClass) throws Exception {
  // Parameters used for optimisation choices...
  boolean exposeProxy = this.advised.isExposeProxy();
  boolean isFrozen = this.advised.isFrozen();
  boolean isStatic = this.advised.getTargetSource().isStatic();

  // Choose an "aop" interceptor (used for AOP calls).
  Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);

  // Choose a "straight to target" interceptor. (used for calls that are
  // unadvised but can return this). May be required to expose the proxy.
  Callback targetInterceptor;
  if (exposeProxy) {
   targetInterceptor = isStatic ?
     new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
     new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());
  }
  else {
   targetInterceptor = isStatic ?
     new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
     new DynamicUnadvisedInterceptor(this.advised.getTargetSource());
  }

  // Choose a "direct to target" dispatcher (used for
  // unadvised calls to static targets that cannot return this).
  Callback targetDispatcher = isStatic ?
    new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp();

  Callback[] mainCallbacks = new Callback[]{
   aopInterceptor, // for normal advice
   targetInterceptor, // invoke target without considering advice, if optimized
   new SerializableNoOp(), // no override for methods mapped to this
   targetDispatcher, this.advisedDispatcher,
   new EqualsInterceptor(this.advised),
   new HashCodeInterceptor(this.advised)
  };

  Callback[] callbacks;

  // If the target is a static one and the advice chain is frozen,
  // then we can make some optimisations by sending the AOP calls
  // direct to the target using the fixed chain for that method.
  if (isStatic && isFrozen) {
   Method[] methods = rootClass.getMethods();
   Callback[] fixedCallbacks = new Callback[methods.length];
   this.fixedInterceptorMap = new HashMap<String, Integer>(methods.length);

   // TODO: small memory optimisation here (can skip creation for
   // methods with no advice)
   for (int x = 0; x < methods.length; x++) {
    List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
    fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
      chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
    this.fixedInterceptorMap.put(methods[x].toString(), x);
   }

   // Now copy both the callbacks from mainCallbacks
   // and fixedCallbacks into the callbacks array.
   callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
   System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
   System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
   this.fixedInterceptorOffset = mainCallbacks.length;
  }
  else {
   callbacks = mainCallbacks;
  }
  return callbacks;
 }
DynamicAdvisedInterceptor留到下一节再介绍。
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);

猜你喜欢

转载自hai19850514.iteye.com/blog/1829569