《Spring AOP面向切面编程》(下)

3.Spring AOP的实现原理

3.2 链式调用

多个AOP 切面是如何叠加起作用的?

public class Proxy implements Subject {

    private RealSubject realSubject;

    public Proxy(RealSubject realSubject) {
        this.realSubject = realSubject;
    }
    /**
    * realSubject.request()是目标方法
    * 在目标方法调用前、调用后、发生异常时,都需要被拦截
    * aop是如何实现将这些调用串起来的?
    */
    public void request() throws Exception{
        //before
        //记录调用次数
        //权限控制,仅管理员可以操作
        //开启事务
        System.out.println("before:记录调用次数"); 
        System.out.println("before:进行权限控制,仅管理员可以进行后续操作");
        System.out.println("before:开启事务");
        try {
            realSubject.request();
        } catch (Exception e) {
            //afterThrowing
            //事务失败,回滚操作
            System.out.println("afterThrowing:事务失败,回滚操作 ex:" + e.getMessage());
            throw e;
        } finally {
            //afterReturning
            //事务成功,提交操作
            System.out.println("afterReturning:事务成功,提交操作");
        }
    }
}

#3.2.1 职责链模式

3.2.1.1 V1

在这里插入图片描述

public abstract class Handler {

    private Handler successor;

    public Handler getSuccessor() {
        return successor;
    }

    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }

    //对外暴露的方法
    public void execute() {
        handleProcess();
        if (successor != null) {
            successor.execute();
        }
    }

    // 需要子类实现
    protected abstract void handleProcess();
}

public class Client {

    static class HandlerA extends Handler {

        @Override
        protected void handleProcess() {
            System.out.println("handle by a");
        }
    }

    static class HandlerB extends Handler {

        @Override
        protected void handleProcess() {
            System.out.println("handle by b");
        }
    }

    static class HandlerC extends Handler {

        @Override
        protected void handleProcess() {
            System.out.println("handle by c");
        }
    }
    //缺点:各个handler之间的顺序需要显式指定
    //handlerA.setSuccessor(handlerB);
    //handlerB.setSuccessor(handlerC);
    public static void main(String[] args) {
        HandlerA handlerA = new HandlerA();
        HandlerB handlerB = new HandlerB();
        HandlerC handlerC = new HandlerC();

        handlerA.setSuccessor(handlerB);
        handlerB.setSuccessor(handlerC);

        handlerA.execute();
    }
}

运行结果

handle by a
handle by b
handle by c

3.2.1.2 V2

public abstract class ChainHandler {

    public void execute(Chain chain) {
        handleProcess();
        chain.proceed();
    }

    protected abstract void handleProcess();
}

public class Chain {
    //将各个handler保存在handlers这个list中
    //各个handler之间的执行顺序由chain来维持
    private List<ChainHandler> handlers;
    private int index = 0;

    public Chain(List<ChainHandler> handlers) {
        this.handlers = handlers;
    }

    public void proceed() {
        if (index >= handlers.size()) {
            return;
        }
        handlers.get(index++).execute(this);
    }
}

public class ChainClient {
    static class ChainHandlerA extends ChainHandler {
        @Override
        protected void handleProcess() {
            System.out.println("handle by a");
        }
    }
    static class ChainHandlerB extends ChainHandler {
        @Override
        protected void handleProcess() {
            System.out.println("handle by b");
        }
    }
    static class ChainHandlerC extends ChainHandler {
        @Override
        protected void handleProcess() {
            System.out.println("handle by c");
        }
    }

    public static void main(String[] args) {
        /**
        在list中的顺序决定了handler的执行顺序
        */
        List<ChainHandler> handlers = Arrays.asList(
                new ChainHandlerA(),
                new ChainHandlerB(),
                new ChainHandlerC()
        );

        Chain chain = new Chain(handlers);
        chain.proceed();
    }
}

运行结果

handle by a
handle by b
handle by c

3.2.2 Spring内部实现

以JDK动态代理为例,调用目标对象的方法时,实际上调用的是代理对象的invoke方法。

JdkDynamicAopProxy的invoke方法

	/**
	 * Implementation of {@code InvocationHandler.invoke}.
	 * <p>Callers will see exactly the exception thrown by the target,
	 * unless a hook method throws an exception.
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		MethodInvocation invocation;
		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]);
			}
			else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
				// The target does not implement the hashCode() method itself.
				return hashCode();
			}
			else if (method.getDeclaringClass() == DecoratingProxy.class) {
				// There is only getDecoratedClass() declared -> dispatch to proxy config.
				return AopProxyUtils.ultimateTargetClass(this.advised);
			}
			else 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;

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

			// May be null. 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<Object> 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.
				Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
				retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
			}
			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.
			Class<?> returnType = method.getReturnType();
			if (retVal != null && retVal == target && returnType.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;
			}
			else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
				throw new AopInvocationException(
						"Null return value from advice does not match primitive return type for: " + method);
			}
			return retVal;
		}
		finally {
			if (target != null && !targetSource.isStatic()) {
				// Must have come from TargetSource.
				targetSource.releaseTarget(target);
			}
			if (setProxyContext) {
				// Restore old proxy.
				AopContext.setCurrentProxy(oldProxy);
			}
		}
	}

JdkDynamicAopProxy的invoke方法核心代码如下:

  //1).得到目标方法的拦截器链
			List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
      //2). 调用拦截器链
      //如果chain是空的,直接调用target对象的method
			if (chain.isEmpty()) {
				Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
				retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
			}
      //如果chain不是空的,进行拦截器链的调用
			else {
				invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
				// Proceed to the joinpoint through the interceptor chain.
				retVal = invocation.proceed();
			}

1)拦截器链是如何生成的

我们顺着this.advised.getInterceptorsAndDynamicInterceptionAdvice往下走。

/**
	 * Determine a list of {@link org.aopalliance.intercept.MethodInterceptor} objects
	 * for the given method, based on this configuration.
	 * @param method the proxied method
	 * @param targetClass the target class
	 * @return List of MethodInterceptors (may also include InterceptorAndDynamicMethodMatchers)
	 */
	public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
		MethodCacheKey cacheKey = new MethodCacheKey(method);
		List<Object> cached = this.methodCache.get(cacheKey);
		if (cached == null) {
			cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
					this, method, targetClass);
			this.methodCache.put(cacheKey, cached);
		}
		return cached;
	}

上面的this.advisorChainFactory其实是DefaultAdvisorChainFactory。

public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializable {

	@Override
	public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
			Advised config, Method method, Class<?> targetClass) {

		// This is somewhat tricky... We have to process introductions first,
		// but we need to preserve order in the ultimate list.
		List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
		Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
		boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
		AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
    //遍历config.getAdvisors
		for (Advisor advisor : config.getAdvisors()) {
			if (advisor instanceof PointcutAdvisor) {
				// Add it conditionally.
				PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
				if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
          //调用registry.getInterceptors得到advisor的MethodInterceptor
					MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
          //调用pointcutAdvisor.getPointcut().getMethodMatcher()得到pointcut的MethodMatcher
					MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
          //调用interceptorList.add将拦截器加入到拦截器链中
					if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
						if (mm.isRuntime()) {
							// Creating a new object instance in the getInterceptors() method
							// isn't a problem as we normally cache created chains.
							for (MethodInterceptor interceptor : interceptors) {
								interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
							}
						}
						else {
							interceptorList.addAll(Arrays.asList(interceptors));
						}
					}
				}
			}
			else if (advisor instanceof IntroductionAdvisor) {
				IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
				if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
					Interceptor[] interceptors = registry.getInterceptors(advisor);
					interceptorList.addAll(Arrays.asList(interceptors));
				}
			}
			else {
				Interceptor[] interceptors = registry.getInterceptors(advisor);
				interceptorList.addAll(Arrays.asList(interceptors));
			}
		}

		return interceptorList;
	}

	/**
	 * Determine whether the Advisors contain matching introductions.
	 */
	private static boolean hasMatchingIntroductions(Advised config, Class<?> actualClass) {
		for (int i = 0; i < config.getAdvisors().length; i++) {
			Advisor advisor = config.getAdvisors()[i];
			if (advisor instanceof IntroductionAdvisor) {
				IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
				if (ia.getClassFilter().matches(actualClass)) {
					return true;
				}
			}
		}
		return false;
	}
}

List getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, Class<?> targetClass)

其实这里的config就是ProxyFactoryBean的实例。(config传入了个AdvisedSupport实例,ProxyFactoryBean继承了AdvisedSupport)
继续找ProxyFactoryBean的代码。
ProxyFactoryBean的getObject方法调用时,会对adviceChain进行初始化(如果未初始化的话)

	@Override
	public Object getObject() throws BeansException {
    //adviceChain拦截器链的初始化
		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();
		}
	}

initializeAdvisorChain的内部实现:
因为ProxyFactoryBean实现了BeanFactoryAware接口,因此可以拿到当前的容器实例beanFactory。
通过调用this.beanFactory.get(beanName)方法将各个advice bean拿出来,然后加入到list中。
initializeAdvisorChain的具体内部实现如下。

	/**
	 * Create the advisor (interceptor) chain. Advisors 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;
	}

总结,在ProxyFactoryBean的getObject方法中,会初始化拦截器链,相关的bean是通过调用beanFactory.get(beanName)方法得到的。

2)拦截器链是如何链式调用的

ReflectiveMethodInvocation.proceed执行拦截器链的调用。

下面摘录了ReflectiveMethodInvocation的部分代码。

//ReflectiveMethodInvocation实现了接口ProxyMethodInvocation,而ProxyMethodInvocation是MethodInvocation的子接口。
//因此,ReflectiveMethodInvocation实现了MethodInvocation接口。
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {

	protected final Object proxy;

	protected final Object target;

	protected final Method method;

	protected Object[] arguments;

	private final Class<?> targetClass;	

/**
	 * List of MethodInterceptor and InterceptorAndDynamicMethodMatcher
	 * that need dynamic checks.
	 */
  //拦截器列表
	protected final List<?> interceptorsAndDynamicMethodMatchers;

	/**
	 * Index from 0 of the current interceptor we're invoking.
	 * -1 until we invoke: then the current interceptor.
	 */
	private int currentInterceptorIndex = -1;	

@Override
	public Object proceed() throws Throwable {
		//	We start with an index of -1 and increment early.
    //如果拦截器list到了最后了,运行目标方法
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			return invokeJoinpoint();
		}
		//根据currentInterceptorIndex得到list中的拦截器
		Object interceptorOrInterceptionAdvice =
				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
    //1.如果拦截器中不仅有Interceptor,还需要进行动态方法匹配DynamicMethodMatcher
    
    //InterceptorAndDynamicMethodMatcher包含了Interceptor和DynamicMethodMatcher,
    //其中DynamicMethodMatcher用于运行时检查,用于在运行时判断方法是否需要拦截
    //(说明:MethodMatcher方法匹配分静态和动态两种
    //个人理解:
    //静态检查:比如你要拦截的方法名是精确的,就是某个类的某个方法,可以在程序非运行时,就可判断是否需要拦截
    //动态检查:比如你要拦截的某个方法,且要求入参为“aaa”,这种肯定需要运行时判断)
		if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
			// Evaluate dynamic method matcher here: static part will already have
			// been evaluated and found to match.
			InterceptorAndDynamicMethodMatcher dm =
					(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
      //1.1 如果匹配上了,调用interceptor的invoke方法
			if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
        //如果匹配上了,调用拦截器方法
        //注意:interceptor.invoke(this)传入的是this。
        //而ReflectiveMethodInvocation实现了MethodInvocation接口
        //因此,传入的是一个MethodInvocation实例。
				return dm.interceptor.invoke(this);
			}
      //1.2 如果没有匹配上,
			else {
				// Dynamic matching failed.
				// Skip this interceptor and invoke the next in the chain.
				return proceed();
			}
		}
    //2. 如果拦截器就是个interceptor,调用invoker方法
		else {
			// It's an interceptor, so we just invoke it: The pointcut will have
			// been evaluated statically before this object was constructed.
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}
	}
}

public interface MethodInterceptor extends Interceptor {
	
	/**
	 * Implement this method to perform extra treatments before and
	 * after the invocation. Polite implementations would certainly
	 * like to invoke {@link Joinpoint#proceed()}.
	 * @param invocation the method invocation joinpoint
	 * @return the result of the call to {@link Joinpoint#proceed();
	 * might be intercepted by the interceptor
	 * @throws Throwable if the interceptors or the target object
	 * throws an exception
	 */
	Object invoke(MethodInvocation invocation) throws Throwable;
}

MethodBeforeAdviceInterceptor:会在目标方法运行之前进行拦截。

public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {
	private MethodBeforeAdvice advice;
	/**
	 * Create a new MethodBeforeAdviceInterceptor for the given advice.
	 * @param advice the MethodBeforeAdvice to wrap
	 */
	public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
		Assert.notNull(advice, "Advice must not be null");
		this.advice = advice;
	}

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
		return mi.proceed();
	}
}

AfterReturningAdviceInterceptor:会在目标方法返回后进行拦截

public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {
	private final AfterReturningAdvice advice;
	/**
	 * Create a new AfterReturningAdviceInterceptor for the given advice.
	 * @param advice the AfterReturningAdvice to wrap
	 */
	public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
		Assert.notNull(advice, "Advice must not be null");
		this.advice = advice;
	}

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		Object retVal = mi.proceed();
		this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
		return retVal;
	}
}

3)Spring使用职责链模式实现拦截器链链式调用

将上面调用拦截器链的简化下,如下。

public interface MethodInterceptor {

    Object invoke(MethodInvocation mi);
}

public class MethodBeforeInterceptor implements MethodInterceptor {

    @Override
    public Object invoke(MethodInvocation mi) {
        before();
        return mi.proceed();
    }

    private void before() {
        System.out.println("Method before");
    }
}
public class AfterReturningInterceptor implements MethodInterceptor {

    @Override
    public Object invoke(MethodInvocation mi) {
        Object retVal = mi.proceed();
        afterReturning();
        return retVal;
    }

    private void afterReturning() {
        System.out.println("afterReturning");
    }
}


public interface MethodInvocation {

    Object proceed();
}

public class ReflectiveMethodInvocation implements MethodInvocation{

    private List<MethodInterceptor> interceptors;

    public ReflectiveMethodInvocation(List<MethodInterceptor> interceptors) {
        this.interceptors = interceptors;
    }

    private int currentInterceptorIndex = -1;

    public Object proceed() {
        if (currentInterceptorIndex == interceptors.size() - 1) {
            System.out.println("invoke target method");
            return "obj after invoke target method";
        }
        return interceptors.get(++currentInterceptorIndex).invoke(this);
    }
}

public class Client {

    public static void main(String[] args) {
        List<MethodInterceptor> interceptors = Arrays.asList(
                new AfterReturningInterceptor(),
                new MethodBeforeInterceptor()
        );
        ReflectiveMethodInvocation invocation = new ReflectiveMethodInvocation(interceptors);
        invocation.proceed();
    }
}

结果如下

Method before
invoke target method
afterReturning

运行结果与List中interceptor的顺序有关吗?
把new AfterReturningInterceptor()和new MethodBeforeInterceptor()换下顺序,结果会不同吗?
答案:无关,不会。

4. ProxyFactory实现AOP

通过配置的方式使用AOP时,是通过ProxyFactoryBean的getObject()方法得到代理对象的。
Spring 提供ProxyFactory类,可以通过编写代码的方式创建代理对象。

  TargetImpl target = new TargetImpl();
        ProxyFactory proxyFactory = new ProxyFactory(target);
        proxyFactory.addAdvisor(yourAdvisor);
        proxyFactory.addAdvice(yourAdvice);
        TargetImpl targetProxy = (TargetImpl)proxyFactory.getProxy();

ProxyFactory类提供的方法如下。

/**
 * Factory for AOP proxies for programmatic use, rather than via a bean
 * factory. This class provides a simple way of obtaining and configuring
 * AOP proxies in code.
 *
 * @author Rod Johnson
 * @author Juergen Hoeller
 * @author Rob Harrop
 * @since 14.03.2003
 */
@SuppressWarnings("serial")
public class ProxyFactory extends ProxyCreatorSupport {

	/**
	 * Create a new ProxyFactory.
	 */
	public ProxyFactory() {
	}
  
	public ProxyFactory(Object target) {
		setTarget(target);
		setInterfaces(ClassUtils.getAllInterfaces(target));
	}

	public ProxyFactory(Class<?>... proxyInterfaces) {
		setInterfaces(proxyInterfaces);
	}

	public ProxyFactory(Class<?> proxyInterface, Interceptor interceptor) {
		addInterface(proxyInterface);
		addAdvice(interceptor);
	}

	public ProxyFactory(Class<?> proxyInterface, TargetSource targetSource) {
		addInterface(proxyInterface);
		setTargetSource(targetSource);
	}

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

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

	@SuppressWarnings("unchecked")
	public static <T> T getProxy(Class<T> proxyInterface, Interceptor interceptor) {
		return (T) new ProxyFactory(proxyInterface, interceptor).getProxy();
	}

	@SuppressWarnings("unchecked")
	public static <T> T getProxy(Class<T> proxyInterface, TargetSource targetSource) {
		return (T) new ProxyFactory(proxyInterface, targetSource).getProxy();
	}

	public static Object getProxy(TargetSource targetSource) {
		if (targetSource.getTargetClass() == null) {
			throw new IllegalArgumentException("Cannot create class proxy for TargetSource with null target class");
		}
		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.setTargetSource(targetSource);
		proxyFactory.setProxyTargetClass(true);
		return proxyFactory.getProxy();
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值