Spring源码学习-5.ProxyFactoryBean实现与源代码分析


1.AOP设计原理

proxyConfig<-AdvisedSupport<-proxyCreatorSupport<-(AspectJProxyFactory+ ProxyFactory + ProxyFactoryBean)

在这个继承关系中,ProxyConfig是最底层的类,这是一个数据基类,为子类提供配置属性
AdvisedSupport: 封装了AOP对通知和通知器的操作
proxyCreatorSupport:子类创建AOP对象的一个辅助类
AspectJProxyFactory:集成AOP和AspectJ
ProxyFactory :封装AOP功能,需要编程式实现
ProxyFactoryBean封装AOP ,在IoC中实现声明式配置


2.第一步:得到AOP代理对象

ProxyFactoryBean生成Aop代理对象

1.配置ProxyFactoryBean

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<span style="white-space:pre">	</span>xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
<span style="white-space:pre">	</span>xmlns:tx="http://www.springframework.org/schema/tx"
<span style="white-space:pre">	</span>xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
<span style="white-space:pre">		</span>http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
<span style="white-space:pre">		</span>http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
<span style="white-space:pre">		</span>http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<span style="white-space:pre">	</span><bean id="testAdvisor" class="day0815.AopAdvisor">
<span style="white-space:pre">	</span></bean>
<span style="white-space:pre">	</span><bean id="ttt" class="day0815.AopTestMethod"></bean>
<span style="white-space:pre">	</span><bean id="testAOP" class="org.springframework.aop.framework.ProxyFactoryBean">
<span style="white-space:pre">		</span><property name="proxyInterfaces" >
<span style="white-space:pre">			</span><value>day0815.TestProxyInterface</value>
<span style="white-space:pre">		</span></property>
<span style="white-space:pre">		</span><property name="target">
<span style="white-space:pre">			</span><ref bean="ttt"/>
<span style="white-space:pre">		</span></property>
<span style="white-space:pre">		</span><property name="interceptorNames" ><list><value>testAdvisor</value></list></property>
<span style="white-space:pre">	</span></bean>
</beans>

target是需要增强的对象

Demo中的代码为
package day0815;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringTest {

	public static void main(String[] args) {
		ApplicationContext a = new ClassPathXmlApplicationContext("classpath:ac20150811.xml");
		TestProxyInterface aopTestMethod = (TestProxyInterface) a.getBean("testAOP");
		aopTestMethod.service();
	}
}//=============================================
package day0815;

public interface TestProxyInterface {

	void service();

}//==============================================
package day0815;

public class AopTestMethod implements TestProxyInterface{

	@Override
	public void service(){
		System.out.println("Service method");
		
	}
}<pre name="code" class="java">//=============================================
package day0815;import java.lang.reflect.Method;import org.springframework.aop.MethodBeforeAdvice;public class AopAdvisor implements MethodBeforeAdvice{@Overridepublic void before(Method arg0, Object[] arg1, Object arg2)throws Throwable {// TODO Auto-generated method stubSystem.out.println("BeforeMethod~~");}}
 

2.生成代理对象

生成代理对象的入口是getObject.由于ProxyFactoryBean也是一个FactoryBean ,
singleton和Prototype生成过程是不同的
//ProxyFactoryBean的实现是以getObject为入口实现的
	public Object getObject() throws BeansException {
		initializeAdvisorChain();//初始化通知器
		if (isSingleton()) {//如果是单例,以单例的方式生成aopProxy代理,Bean的默认就是单例,所以进入这个方法
			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();
		}
	}
	
下面是通知器初始过程,
advisorChainInitialized是是否已经初始化的标志,如果已经初始化就返回
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.
			//添加Advisor链的调用,通过interceptorNames进行的
			for (int i = 0; i < this.interceptorNames.length; i++) {
				String name = this.interceptorNames[i];
				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.
					//需要加入命名的拦截器Advice
					Object advice = null;
					if (this.singleton || this.beanFactory.isSingleton(this.interceptorNames[i])) {
						// Add the real Advisor/Advice to the chain.
						//调用getBean加载通知器或者通知
						advice = this.beanFactory.getBean(this.interceptorNames[i]);
					}
					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(this.interceptorNames[i]);
					}
					addAdvisorOnChainCreation(advice, this.interceptorNames[i]);
				}
			}
		}
		//已初始化,不需要再次初始化
		this.advisorChainInitialized = true;
	}

singleton代理对象的生成是在getSingletonInstance中,这是生成代理对象的入口,

	//生成代理代理对象
	private synchronized Object getSingletonInstance() {
		if (this.singletonInstance == null) {
		//获取target属性
			this.targetSource = freshTargetSource();
			if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
				// Rely on AOP infrastructure to tell us what interfaces to proxy.
				//根据aop框架来判断需要代理的接口
				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;
	}
获取代理对象

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

AopProxy是一个接口,他把代理对象的实现与框架分隔开
有两个子类实现了AopProxy
一个是JdkDynamicProxy,另一个是Cglib2AopProxy
createAopProxy生成aopProxy对象
//ProxyCreatorSupport类中的方法
	protected final synchronized AopProxy createAopProxy() {
		if (!this.active) {
			activate();
		}
		return getAopProxyFactory().createAopProxy(this);
	}

这里利用AopProxyFactory来创建AopProxy

	//DefaultAopProxyFactory类中的方法
	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.");
			}
			//如果support是接口,用jdk来生成代理
			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.");
			}
			//否则用cglib来生成
			return CglibProxyFactory.createCglibProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}

3.JDK和cglib生成AOP代理对象

1.使用jdk生成
	//JDK生成代理对象
	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);
	}
	
	//实现InvocationHandler接口需要实现的方法
		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		MethodInvocation invocation = null;
		Object oldProxy = null;
		boolean setProxyContext = false;

		TargetSource targetSource = this.advised.targetSource;
		Class targetClass = null;
		Object target = null;

		try {
			if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
				// The target does not implement the equals(Object) method itself.
				return (equals(args[0]) ? Boolean.TRUE : Boolean.FALSE);
			}
			if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
				// The target does not implement the hashCode() method itself.
				return new Integer(hashCode());
			}
			if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
					method.getDeclaringClass().isAssignableFrom(Advised.class)) {
				// Service invocations on ProxyConfig with the proxy config...
				return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
			}

			Object retVal = null;

			if (this.advised.exposeProxy) {
				// Make invocation available if necessary.
				oldProxy = AopContext.setCurrentProxy(proxy);
				setProxyContext = true;
			}

			// May be <code>null</code>. Get as late as possible to minimize the time we "own" the target,
			// in case it comes from a pool.
			target = targetSource.getTarget();
			if (target != null) {
				targetClass = target.getClass();
			}

			// Get the interception chain for this method.
			List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

			// Check whether we have any advice. If we don't, we can fallback on direct
			// reflective invocation of the target, and avoid creating a MethodInvocation.
			if (chain.isEmpty()) {
				// We can skip creating a MethodInvocation: just invoke the target directly
				// Note that the final invoker must be an InvokerInterceptor so we know it does
				// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
				retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
			}
			else {
				// We need to create a method invocation...
				invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
				// Proceed to the joinpoint through the interceptor chain.
				retVal = invocation.proceed();
			}

			// Massage return value if necessary.
			if (retVal != null && retVal == target && method.getReturnType().isInstance(proxy) &&
					!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
				// Special case: it returned "this" and the return type of the method
				// is type-compatible. Note that we can't help if the target sets
				// a reference to itself in another returned object.
				retVal = proxy;
			}
			return retVal;
		}
		finally {
			if (target != null && !targetSource.isStatic()) {
				// Must have come from TargetSource.
				targetSource.releaseTarget(target);
			}
			if (setProxyContext) {
				// Restore old proxy.
				AopContext.setCurrentProxy(oldProxy);
			}
		}
	}

2.使用cglib生成代理对象

//Cglib2AopProxy类中的方法
//使用cglib来生成代理对象

	public Object getProxy(ClassLoader classLoader) {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating CGLIB2 proxy: target source is " + this.advised.getTargetSource());
		}

		try {
			//IoC容器中配制的Target对象

			Class rootClass = this.advised.getTargetClass();
			Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
			
			Class proxySuperClass = rootClass;
			//如果这个类是cglib产生的,proxySuperClass = rootClass.getSuperclass();
			if (AopUtils.isCglibProxyClass(rootClass)) {
				proxySuperClass = rootClass.getSuperclass();
				Class[] additionalInterfaces = rootClass.getInterfaces();
				for (int i = 0; i < additionalInterfaces.length; i++) {
					Class additionalInterface = additionalInterfaces[i];
					this.advised.addInterface(additionalInterface);
				}
			}

			// Validate the class, writing log messages as necessary.
			
			validateClassIfNecessary(proxySuperClass);
			//验证代理对象的接口
			//生成Enhancer
			// 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);
			//创建一个cglib代理的实例
			// 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);
		}
	}

4.第二步:AOP拦截器调用的实现

1.JDK
拦截器的设置在使用jdk或者cglib生成代理对象时就完成了,
如果是JDK的Proxy来实现代理对象的话,那么需要在InvocationHandler中来设置回调

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);//这个类继承了InvocationHandler接口,所以在这个类的invoke中 可以看到配置的过程
	}

//JdkDynamicAopProxy类invoke方法
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		MethodInvocation invocation = null;
		Object oldProxy = null;
		boolean setProxyContext = false;

		TargetSource targetSource = this.advised.targetSource;
		Class targetClass = null;
		Object target = null;

		try {
			if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
				// The target does not implement the equals(Object) method itself.
				//如果目标没实现equals方法
				return (equals(args[0]) ? Boolean.TRUE : Boolean.FALSE);
			}
			if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
				// The target does not implement the hashCode() method itself.
				//如果目标没实现hashcode
				return new Integer(hashCode());
			}
			if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
					method.getDeclaringClass().isAssignableFrom(Advised.class)) {
				// Service invocations on ProxyConfig with the proxy config...
				//根据代理对象的配置调用服务
				return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
			}

			Object retVal = null;

			if (this.advised.exposeProxy) {
				// Make invocation available if necessary.
				oldProxy = AopContext.setCurrentProxy(proxy);
				setProxyContext = true;
			}

			// May be <code>null</code>. Get as late as possible to minimize the time we "own" the target,
			// in case it comes from a pool.
			//得到目标对象
			target = targetSource.getTarget();
			if (target != null) {
				targetClass = target.getClass();
			}
			//得到定义好的连接器链
			// Get the interception chain for this method.
			List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

			// Check whether we have any advice. If we don't, we can fallback on direct
			//构造MethodInvocation
			// reflective invocation of the target, and avoid creating a MethodInvocation.
			if (chain.isEmpty()) {
				// We can skip creating a MethodInvocation: just invoke the target directly
				// Note that the final invoker must be an InvokerInterceptor so we know it does
				// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
				//没有设定拦截器,就直接调用target的对应方法
				retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
			}
			else {
				// We need to create a method invocation...
				//如果有设置拦截器,我们需调用拦截器后,再调用目标对象的方法
				invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
				// Proceed to the joinpoint through the interceptor chain.
				//沿着拦截器继续前进
				retVal = invocation.proceed();
			}

			// Massage return value if necessary.
			if (retVal != null && retVal == target && method.getReturnType().isInstance(proxy) &&
					!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
				// Special case: it returned "this" and the return type of the method
				// is type-compatible. Note that we can't help if the target sets
				// a reference to itself in another returned object.
				retVal = proxy;
			}
			return retVal;
		}
		finally {
			if (target != null && !targetSource.isStatic()) {
				// Must have come from TargetSource.
				targetSource.releaseTarget(target);
			}
			if (setProxyContext) {
				// Restore old proxy.
				AopContext.setCurrentProxy(oldProxy);
			}
		}
	}

2.CGLIB
this代表了这个类,这个类继承了InvocationHandler接口,所以在这个类的invoke中 可以看到配置的过程

如果是CGLIB的话,需要根据cglib使用要求,在dynamic-AdvisedInterceptor中完成.

CGLIB与jdk的实现类似,只是通过构造ReflectMethod-Invocation对象来完成

		public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
			MethodInvocation invocation = null;
			Object oldProxy = null;
			boolean setProxyContext = false;
			Class targetClass = null;
			Object target = null;
			try {
				Object retVal = null;
				if (this.advised.exposeProxy) {
					// Make invocation available if necessary.
					oldProxy = AopContext.setCurrentProxy(proxy);
					setProxyContext = true;
				}
				// May be <code>null</code>. Get as late as possible to minimize the time we
				// "own" the target, in case it comes from a pool.
				target = getTarget();
				if (target != null) {
					targetClass = target.getClass();
				}
				List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
				// Check whether we only have one InvokerInterceptor: that is,
				// no real advice, but just reflective invocation of the target.
				if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
					// We can skip creating a MethodInvocation: just invoke the target directly.
					// Note that the final invoker must be an InvokerInterceptor, so we know
					// it does nothing but a reflective operation on the target, and no hot
					// swapping or fancy proxying.
					retVal = methodProxy.invoke(target, args);
				}
				else {
					// We need to create a method invocation...
					invocation = new CglibMethodInvocation(proxy, target, method, args,
							targetClass, chain, methodProxy);
					// If we get here, we need to create a MethodInvocation.
					retVal = invocation.proceed();
				}

				retVal = massageReturnTypeIfNecessary(proxy, target, method, retVal);
				return retVal;
			}
			finally {
				if (target != null) {
					releaseTarget(target);
				}
				if (setProxyContext) {
					// Restore old proxy.
					AopContext.setCurrentProxy(oldProxy);
				}
			}
		}


3.对于目标方法的调用

jdk的实现方法是使用反射得出的,而cglib是通过MethodProxy完成的

5.AOP拦截器链的调用

1.处理AOP配置的通知基本步骤:

(1).获取AOP配置的通知Advice

AOP动态代理对象的回调方法中,都需要使用以下方式获取AOP配置的通知,并将获取到的通知和目标对象、代理对象等一起封装为ReflectiveMethodInvocation对象


//获取AOP配置的通知  
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);  
……  
//根据获取的通知、目标对象等创建ReflectiveMethodInvocation  
//如果是CGLIB方式,则创建CglibMethodInvocation对象:  
//new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy);  
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);  
//沿着获取的通知链,递归调用所有配置的AOP通知  
retVal = invocation.proceed();  

(2).创建ReflectiveMethodInvocation对象:

a.创建CglibMethodInvocation对象:

(3).处理AOP配置的通知器:
Spring通过调用ReflectiveMethodInvocation类来处理AOP配置的通知,CglibMethodInvocation继承ReflectiveMethodInvocation,因此JDK和CGLIB方式都是通过调用ReflectiveMethodInvocation的proceed()方法来处理通知的,处理通知的源码如下:

/处理AOP配置的通知  
public Object proceed() throws Throwable {  
        //如果拦截器链中通知已经调用完毕  
        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {  
            //这个方法调用AopUtils.invokeJoinpointUsingReflection方法,  
//通过反射机制直接调用目标对象方法  
            return invokeJoinpoint();  
        }  
        //获取AOP配置的通知,在ReflectiveMethodInvocation初始化构方法中将获  
//取到的AOP通知赋值给interceptorsAndDynamicMethodMatchers变量  
        Object interceptorOrInterceptionAdvice =        this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);  
        //如果获取的通知器或通知是动态匹配方法拦截器类型  
        if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {  
            //动态匹配方法拦截器  
            InterceptorAndDynamicMethodMatcher dm =  
                (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;  
            if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {  
                //如果匹配,调用拦截器的方法  
                return dm.interceptor.invoke(this);  
            }  
            else {  
                //如果不匹配,递归调用proceed()方法,知道拦截器链被全部调用为止  
                return proceed();  
            }  
        }  
        else {  
            //如果不是动态匹配方法拦截器,则切入点在构造对象之前进行静态匹配,调用  
            //拦截器的方法  
            return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);  
        }  
    }  


advisor是怎么产生的那?


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是Spring5的配置文件,该文件配置了Spring5 AOP中的通知,请分析代码并回答后面的问题。(10分) ‎ ​applicationContext.xml: ‎ ​① <?xml version="1.0" encoding="UTF-8"?> ‎ ​② <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" ‎ ​ "https://www.springframework.org/dtd/spring-beans-2.0.dtd" [ ‎ ​<!ENTITY contextInclude SYSTEM ‎ ​ "org/springframework/web/context/WEB-INF/contextInclude.xml">]> ‎ ​③ <beans> ‎ ​④  <bean id="BeforeAdvice" ‎ ​⑤  class="adviceexample.GettingBeforeAdvice"></bean> ‎ ​⑥  <bean id="AfterAdvice" class="adviceexample.GettingAfterAdvice"></bean> ‎ ​⑦  <bean id="proxy" ‎ ​⑧  class="org.springframework.aop.framework.ProxyFactoryBean"> ‎ ​⑨  <property name="proxyInterfaces" ‎ ​⑩  value="adviceexample.Reception"></property> ‎ ​⑪  <property name="interceptorNames"> ‎ ​⑫  <list> ‎ ​⑬  <value>BeforeAdvice</value> ‎ ​⑭  <value>AfterAdvice</value> ‎ ​⑮  </list> ‎ ​⑯  </property> ‎ ​⑰  <property name="target" ref="target"></property> ‎ ​⑱  </bean> ‎ ​⑲  <bean id="target" class="adviceexample.ConcreteReception"></bean> ‎ ​⑳ </beans> ‎ ​(1)上面文件配置了的两种通知是用来做什么的(4分) ‎ ​(2)上面文件配置了代理工厂对象proxy,该对象有三个属性,依次是代理接口,通知和目标对象,其中,代理接口是什么?(2分) ‎ ​(3)分析上面代码说明AOP主要包含哪些内容?(4分)
最新发布
05-11

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值