ProxyFactoryBean

2020-04-10  本文已影响0人  北海北_6dc3

是什么?

解决什么问题

简单示例

@Component
public class MyBeforeAop implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("before aop ["+method.getName()+"] do sth...................");
    }
}
public interface ServInter {
     void say();
}
@Service
public class MyService implements ServInter {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void say() {
        System.out.println("MyService say:" + name);
    }
}

调用

public class Test {

    public static void main(String[] args) {


        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext("com.example.aop.proxyfactorybean");

        //aop3  实际的spring使用aop的过程,配置好ProxyFactoryBean,给ProxyFactoryBean设置一个bean id
        //然后通过ac.getBean(bean id),就取得被ProxyFactoryBean代理的对象,不是ProxyFactoryBean
        //因为这个bean id虽然代表ProxyFactoryBean对象,直接getBean获取的是ProxyFactoryBean.getObject()返回的对象,即代理对象
        //ac.getBean(&bean id),才能取得ProxyFactoryBean对象

        ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
        proxyFactoryBean.setBeanFactory(ac.getBeanFactory());
        //aop拦截处理类
        proxyFactoryBean.setInterceptorNames("myBeforeAop");
        //代理的接口
        proxyFactoryBean.setInterfaces(ServInter.class);
        //被代理对象
        proxyFactoryBean.setTarget(ac.getBean(ServInter.class));
        //放入bean工厂,实际开发是在config下使用注解,设置多个proxyFactoryBean代理,设置不同bean id
        ac.getBeanFactory().registerSingleton("myproxy",proxyFactoryBean);

        ServInter servInterProxy = (ServInter) ac.getBean("myproxy");
        servInterProxy.say();
        //获取直接的ProxyFactoryBean对象,加&
        System.out.println(ac.getBean("&myproxy"));
    }
}

上面其中有一行代码比较诡异,我们来看看

        //放入bean工厂,实际开发是在config下使用注解,设置多个proxyFactoryBean代理,设置不同bean id
        ac.getBeanFactory().registerSingleton("myproxy",proxyFactoryBean);
        ServInter servInterProxy = (ServInter) ac.getBean("myproxy");

我们换一种写法

        ServInter servInterProxy = (ServInter)proxyFactoryBean.getObject();

内部原理

我们先考虑第一种情况jdk实现。

    public Object getObject() throws BeansException {
        initializeAdvisorChain();
        //单例 single
        if (isSingleton()) {
            return getSingletonInstance();
        }
        //原型prototype
        else {
            return newPrototypeInstance();
        }
    }

考虑一下,jdk代理的核心

(T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);

我们看看哪个方法实现了此方法,在aop代理中

    this.singletonInstance = getProxy(createAopProxy());

    protected Object getProxy(AopProxy aopProxy) {
        return aopProxy.getProxy(this.proxyClassLoader);
    }

    @Override
    public Object getProxy(@Nullable ClassLoader classLoader) {
        if (logger.isTraceEnabled()) {
            logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
        }
        Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
        findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
        //看着一句话,最终核心。代理对象生成
        return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
    }

参考jdk代理,链接:---
我们知道关键两个参数,一个是proxiedInterfaces,一个是this。我们首先看下this参数的来源
根据上面代码,可以看出this对象应该是createAopProxy()

public class ProxyCreatorSupport extends AdvisedSupport {
    private AopProxyFactory aopProxyFactory;
    /**
     * Create a new ProxyCreatorSupport instance.
     */
    public ProxyCreatorSupport() {
        this.aopProxyFactory = new DefaultAopProxyFactory();
    }

    /**
     * Return the AopProxyFactory that this ProxyConfig uses.
     */
    public AopProxyFactory getAopProxyFactory() {
        return this.aopProxyFactory;
    }
    //从这里开始看,入口
    protected final synchronized AopProxy createAopProxy() {
        if (!this.active) {
            activate();
        }
        return getAopProxyFactory().createAopProxy(this);
    }
}

//createAopProxy
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
    @Override
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        return new JdkDynamicAopProxy(config);
    }
}
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
    public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
        this.advised = config;
    }
}

我们可以看到this是JdkDynamicAopProxy ,通过config与外界关联。
确认第一点:
this=JdkDynamicAopProxy ;

我们现在来考虑接口,采用逆向看的原则

Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);

其中上一步知道this.advised=config

public abstract class AopProxyUtils {
    static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) {
        Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces();
        //其他逻辑
        Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount];
        System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length);
        //其他逻辑
        return proxiedInterfaces;
}

public class AdvisedSupport extends ProxyConfig implements Advised {

    private List<Class<?>> interfaces = new ArrayList<>();

    @Override
    public Class<?>[] getProxiedInterfaces() {
        return ClassUtils.toClassArray(this.interfaces);
    }
}

那么interfaces 如何赋值的呢。
从我们的入口代码,很容易看出

        //代理的接口
        proxyFactoryBean.setInterfaces(ServInter.class);

public class AdvisedSupport extends ProxyConfig implements Advised {
    public void setInterfaces(Class<?>... interfaces) {
        this.interfaces.clear();
        for (Class<?> ifc : interfaces) {
            addInterface(ifc);
        }
    }

    public void addInterface(Class<?> intf) {
        if (!this.interfaces.contains(intf)) {
            this.interfaces.add(intf);
            adviceChanged();
        }
    }
}

这一步,代理代理接口和this对象解决了

那么代理的最后一步,是实现代理的InvocationHandler接口
我们看定义

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
    @Override
    @Nullable
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object oldProxy = null;
        boolean setProxyContext = false;

        TargetSource targetSource = this.advised.targetSource;
        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;
            }

            // Get as late as possible to minimize the time we "own" the target,
            // in case it comes from a pool.
            target = targetSource.getTarget();
            Class<?> targetClass = (target != null ? target.getClass() : null);

            // 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...
                MethodInvocation 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 != Object.class && 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);
            }
        }
    }
}

东西有点多,我们一点点分析。
首先参考jdk代理,我们知道核心一定会存在的一个东西。

 Object result = method.invoke(target, args);

我们根据上面来查找。但是,,没有搜到。根据参数来,查找,一定需要target,和args

            //分析下,没有拦截器的情况下,直接执行
            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);
            }




    @Nullable
    public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args)
            throws Throwable {
            ReflectionUtils.makeAccessible(method);
            return method.invoke(target, args);
    }

这里知道 AopUtils.invokeJoinpointUsingReflection这里就是最终的调用。
但是,其实,我们知道,这个执行,是有顺序的,我们支持方法执行前,执行后,环绕,异常等,而这里的代码显然实现不了


image.png

有拦截器的情况下

            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
            if (chain.isEmpty()) {
                ..
            else {
                // We need to create a method invocation...
                MethodInvocation invocation =
                        new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
                // Proceed to the joinpoint through the interceptor chain.
                retVal = invocation.proceed();
            }

public class AdvisedSupport extends ProxyConfig implements Advised {
    public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable 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.getInterceptorsAndDynamicInterceptionAdvice
public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializable {
    @Override
    public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
            Advised config, Method method, @Nullable Class<?> targetClass) {

        AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
        Advisor[] advisors = config.getAdvisors();
        List<Object> interceptorList = new ArrayList<>(advisors.length);
        Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
        Boolean hasIntroductions = null;
        //循环切面,根据下面切面可以分为PointcutAdvisor、IntroductionAdvisor
        for (Advisor advisor : advisors) {
            if (advisor instanceof PointcutAdvisor) {
                // Add it conditionally.
                PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
                if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
                    MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
                    boolean match;
                    if (mm instanceof IntroductionAwareMethodMatcher) {
                        if (hasIntroductions == null) {
                            hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
                        }
                        match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
                    }
                    else {
                        match = mm.matches(method, actualClass);
                    }
                    if (match) {
                        MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
                        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;
    }

}

上面代码,首先根据遍历切面advisors,根据切面类型:【PointcutAdvisor、IntroductionAdvisor、其他】执行相应做操。
那么是如何包装的你?我们传入的拦截类实现的接口为:Advice

public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
        if (adviceObject instanceof Advisor) {
            return (Advisor) adviceObject;
        }
        if (!(adviceObject instanceof Advice)) {
            throw new UnknownAdviceTypeException(adviceObject);
        }
        Advice advice = (Advice) adviceObject;
        if (advice instanceof MethodInterceptor) {
            // So well-known it doesn't even need an adapter.
            return new DefaultPointcutAdvisor(advice);
        }
        for (AdvisorAdapter adapter : this.adapters) {
            // Check that it is supported.
            if (adapter.supportsAdvice(advice)) {
                return new DefaultPointcutAdvisor(advice);
            }
        }
        throw new UnknownAdviceTypeException(advice);
    }

可以看到,如果实现了Advisor接口,则直接返回,如果实现了Advice,则包装,我们的例子中,传递是的一个实现Advice的接口。故会被包装为一个DefaultPointcutAdvisor对象。
查下DefaultPointcutAdvisor

public class DefaultPointcutAdvisor extends AbstractGenericPointcutAdvisor implements Serializable {
    private Pointcut pointcut = Pointcut.TRUE;
    //构造函数
    public DefaultPointcutAdvisor(Advice advice) {
        this(Pointcut.TRUE, advice);
    }
}

其中Pointcut参数
/**
 *  一个切面点由ClassFilter和MethodMatcher组成,用于组合判定是否允许在方法上执行
 */
public interface Pointcut {

    /**
     * Return the ClassFilter for this pointcut.
     * @return the ClassFilter (never {@code null})
     */
    ClassFilter getClassFilter();

    /**
     * Return the MethodMatcher for this pointcut.
     * @return the MethodMatcher (never {@code null})
     */
    MethodMatcher getMethodMatcher();


    /**
     * Canonical Pointcut instance that always matches.
     */
    Pointcut TRUE = TruePointcut.INSTANCE;

}


 TruePointcut.INSTANCE定义
final class TruePointcut implements Pointcut, Serializable {

    public static final TruePointcut INSTANCE = new TruePointcut();

    /**
     * Enforce Singleton pattern.
     */
    private TruePointcut() {
    }

    @Override
    public ClassFilter getClassFilter() {
        return ClassFilter.TRUE;
    }

    @Override
    public MethodMatcher getMethodMatcher() {
        return MethodMatcher.TRUE;
    }

    /**
     * Required to support serialization. Replaces with canonical
     * instance on deserialization, protecting Singleton pattern.
     * Alternative to overriding {@code equals()}.
     */
    private Object readResolve() {
        return INSTANCE;
    }

    @Override
    public String toString() {
        return "Pointcut.TRUE";
    }

}

上面,我们可以看出,ponit主要用于控制,是否匹配
继续查看advice

public abstract class AbstractGenericPointcutAdvisor extends AbstractPointcutAdvisor {
    private Advice advice = EMPTY_ADVICE;
    /**
     * Specify the advice that this advisor should apply.
     */
    public void setAdvice(Advice advice) {
        this.advice = advice;
    }
    @Override
    public Advice getAdvice() {
        return this.advice;
    }
}

最终包装,通过getAdvice,可以获取。并且实现了AbstractPointcutAdvisor类,在其中增加排序功能

public abstract class AbstractPointcutAdvisor implements PointcutAdvisor, Ordered, Serializable {
    @Nullable
    private Integer order;
}

public interface PointcutAdvisor extends Advisor {
    Pointcut getPointcut();
}

public interface Advisor {

    Advice EMPTY_ADVICE = new Advice() {};

    Advice getAdvice();

    boolean isPerInstance();
}

advisors来源已经清楚了,我们继续回到方法 public List<Object> getInterceptorsAndDynamicInterceptionAdvice,根据逻辑,我们将执行

if (advisor instanceof PointcutAdvisor) {
        if (match) {
            MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
            if (mm.isRuntime()) {
                for (MethodInterceptor interceptor : interceptors) {
                    interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
                }
            }
            else {
                interceptorList.addAll(Arrays.asList(interceptors));
            }
        }
}



public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {

    private final List<AdvisorAdapter> adapters = new ArrayList<>(3);


    /**
     * Create a new DefaultAdvisorAdapterRegistry, registering well-known adapters.
     */
    public DefaultAdvisorAdapterRegistry() {
        registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
        registerAdvisorAdapter(new AfterReturningAdviceAdapter());
        registerAdvisorAdapter(new ThrowsAdviceAdapter());
    }

    //registry.getInterceptors(advisor);
    @Override
    public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
        List<MethodInterceptor> interceptors = new ArrayList<>(3);
        Advice advice = advisor.getAdvice();
        if (advice instanceof MethodInterceptor) {
            interceptors.add((MethodInterceptor) advice);
        }
        for (AdvisorAdapter adapter : this.adapters) {
            //根据我们继承拦截继承接口确认使用,adapters见上面定义,根据我们的接口定义
            // 我们的adapter是MethodBeforeAdviceAdapter
            if (adapter.supportsAdvice(advice)) {
                interceptors.add(adapter.getInterceptor(advisor));
            }
        }
        if (interceptors.isEmpty()) {
            throw new UnknownAdviceTypeException(advisor.getAdvice());
        }
        return interceptors.toArray(new MethodInterceptor[0]);
    }
}

具体MethodBeforeAdviceAdapter,此控制匹配和执行顺序

class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {
    //匹配接口,策略模式
    @Override
    public boolean supportsAdvice(Advice advice) {
        return (advice instanceof MethodBeforeAdvice);
    }
    //生成相应拦截
    @Override
    public MethodInterceptor getInterceptor(Advisor advisor) {
        MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
        return new MethodBeforeAdviceInterceptor(advice);
    }

}


public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {

    private final 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;
    }

    //这里可以看到,会先执行before,即我们MyBeforeAop中定义的方法,然后继续执行 mi.proceed();
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
        return mi.proceed();
    }
}

跟踪下 mi.proceed();,实现类只有一个

public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
    @Override
    @Nullable
    public Object proceed() throws Throwable {
        // We start with an index of -1 and increment early.
        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
            return invokeJoinpoint();
        }
        Object interceptorOrInterceptionAdvice =
                this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
        if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
            // Evaluate dynamic method matcher here: static part will already have
            // been evaluated and found to match.
            InterceptorAndDynamicMethodMatcher dm =
                    (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
            Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
            if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
                return dm.interceptor.invoke(this);
            }
            else {
                // Dynamic matching failed.
                // Skip this interceptor and invoke the next in the chain.
                return proceed();
            }
        }
        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);
        }
    }

}

逻辑比较简单,拦截链遍历完成则调用return invokeJoinpoint();,即方法的调用。否则,继续调用拦截器,责任链模式
我们考虑下,如果是一个AfterReturningAdvice

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;
    }
}

和before相似,就是调用顺序换了一下。

总结

1、根据this.interceptorNames,初始化拦截器bean,并包装为相应的interceptor
2、根据类,选择jdk代理或cglib代理【策略模式?】
3、如果是jdk代理,则使用Proxy.newProxyInstance创建代理
4、实现InvocationHandler接口,采用责任链模式,策略模式配合ReflectiveMethodInvocation .proccessed使用。实现方法前,方法后,异常处理。
参考资料:
学习Spring源码(三) AOP原理之实现篇

上一篇下一篇

猜你喜欢

热点阅读