网站顶部布局上饶做网站最好的公司
web/
2025/9/27 19:19:38/
文章来源:
网站顶部布局,上饶做网站最好的公司,深圳宝安西乡网站建设,制作网页需要什么技术文章目录 系列文档索引五、ProxyFactory源码分析1、案例2、认识TargetSource#xff08;1#xff09;何时用到TargetSource#xff08;2#xff09;Lazy的原理#xff08;3#xff09;应用TargetSource 3、ProxyFactory选择cglib或jdk动态代理原理4、jdk代理获取代理方法… 文章目录 系列文档索引五、ProxyFactory源码分析1、案例2、认识TargetSource1何时用到TargetSource2Lazy的原理3应用TargetSource 3、ProxyFactory选择cglib或jdk动态代理原理4、jdk代理获取代理方法的逻辑1getInterceptorsAndDynamicInterceptionAdvice获取拦截器链2包装AfterReturningAdvice、MethodBeforeAdvice为MethodInterceptor3总结 5、cglib代理获取代理方法的逻辑1getCallbacks获取callback方法2总结 6、执行器链执行逻辑 系列文档索引
SpringAOP从入门到源码分析大全一熟悉动态代理 SpringAOP从入门到源码分析大全二熟悉ProxyFactory SpringAOP从入门到源码分析大全三ProxyFactory源码分析 SpringAOP从入门到源码分析大全四SpringAOP的源码分析 SpringAOP从入门到源码分析大全五手写一个编程式AOP
五、ProxyFactory源码分析
1、案例
UserService userService new UserService();
// spring 将cglib和jdk动态代理合二为一了如果有接口就会走jdk代理如果只有类就会走cglib代理
ProxyFactory proxyFactory new ProxyFactory();
proxyFactory.setTarget(userService);
// 可以设置多个Advice会形成代理链
proxyFactory.addAdvice(new MyBeforeAdvice());
proxyFactory.addAdvice(new MyAroundAdvice());
proxyFactory.addAdvice(new MyAfterAdvice());proxyFactory.addAdvisor(new PointcutAdvisor() {Overridepublic Pointcut getPointcut() {return new Pointcut() {Overridepublic ClassFilter getClassFilter() {return new ClassFilter() {Overridepublic boolean matches(Class? clazz) {// 类匹配器return false;}};}Overridepublic MethodMatcher getMethodMatcher() {// 方法匹配器return new MethodMatcher() {Overridepublic boolean matches(Method method, Class? targetClass) {return false;}Overridepublic boolean isRuntime() {return false; // 如果为true时下面的参数matches就会生效}Overridepublic boolean matches(Method method, Class? targetClass, Object... args) {return false;}};}};}Overridepublic Advice getAdvice() {return new MyAfterAdvice();}// 没用Overridepublic boolean isPerInstance() {return true;}
});UserService proxy (UserService) proxyFactory.getProxy();proxy.test();2、认识TargetSource
1何时用到TargetSource
我们在调用proxyFactory.setTarget方法时是将原始对象封装为了SingletonTargetSource。 SingletonTargetSource实现了TargetSource接口相当于非常简单的一个TargetSource。
// 动态目标源可以支持池化、热插拔等。
public interface TargetSource extends TargetClassAware {// 返回TargetSource返回的目标类型。OverrideNullableClass? getTargetClass();// true表示目标不可变意味着会缓存Targetboolean isStatic();// 返回目标实例。在AOP框架调用AOP方法调用的“目标”之前立即调用。NullableObject getTarget() throws Exception;// 释放从getTarget()方法获得的给定目标对象(如果有的话)。void releaseTarget(Object target) throws Exception;}
其实AOP代理的对象每次调用代理对象的方法时获取的原始对象就是从TargetSource 的getTarget方法中获取的这就意味着具备了很强的灵活性。
2Lazy的原理
Autowired
private UserService userService;在属性注入时使用Lazy注解并不会初始化Bean而是将代理对象赋值给了属性。
我们看一下Lazy属性赋值的源码
// org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver#buildLazyResolutionProxy
protected Object buildLazyResolutionProxy(final DependencyDescriptor descriptor, final Nullable String beanName) {BeanFactory beanFactory getBeanFactory();Assert.state(beanFactory instanceof DefaultListableBeanFactory,BeanFactory needs to be a DefaultListableBeanFactory);final DefaultListableBeanFactory dlbf (DefaultListableBeanFactory) beanFactory;TargetSource ts new TargetSource() {Overridepublic Class? getTargetClass() {return descriptor.getDependencyType();}Overridepublic boolean isStatic() {return false;}Overridepublic Object getTarget() {SetString autowiredBeanNames (beanName ! null ? new LinkedHashSet(1) : null);Object target dlbf.doResolveDependency(descriptor, beanName, autowiredBeanNames, null);if (target null) {Class? type getTargetClass();if (Map.class type) {return Collections.emptyMap();}else if (List.class type) {return Collections.emptyList();}else if (Set.class type || Collection.class type) {return Collections.emptySet();}throw new NoSuchBeanDefinitionException(descriptor.getResolvableType(),Optional dependency not present for lazy injection point);}if (autowiredBeanNames ! null) {for (String autowiredBeanName : autowiredBeanNames) {if (dlbf.containsBean(autowiredBeanName)) {dlbf.registerDependentBean(autowiredBeanName, beanName);}}}return target;}Overridepublic void releaseTarget(Object target) {}};ProxyFactory pf new ProxyFactory();pf.setTargetSource(ts);Class? dependencyType descriptor.getDependencyType();if (dependencyType.isInterface()) {pf.addInterface(dependencyType);}return pf.getProxy(dlbf.getBeanClassLoader());
}上面的源码可以看出就是将属性赋值了一个代理对象而TargetSource 的getTarget方法就是从容器中获取目标对象的Bean进行返回。很巧妙的实现了懒加载。
3应用TargetSource
实际上我们日常开发中很少会用到TargetSource。
我们也可以使用TargetSource实现懒加载、池化每次获取Target都是从池子里获取、热插拔每次获取Target都是重新获取。
3、ProxyFactory选择cglib或jdk动态代理原理
ProxyFactory在生成代理对象之前需要决定到底是使用JDK动态代理还是CGLIB技术
// org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy
Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {// 是GraalVM 就直接用jdk代理// Optimize true或者isProxyTargetClass true 或者配置了接口就走jdkif (!NativeDetector.inNativeImage() (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.);}// 被代理的类是接口 或 被代理的类已经是jdk代理类了 或 lambda表达式 就用jdkif (targetClass.isInterface() || Proxy.isProxyClass(targetClass) || ClassUtils.isLambdaClass(targetClass)) {return new JdkDynamicAopProxy(config);}return new ObjenesisCglibAopProxy(config);}else {return new JdkDynamicAopProxy(config);}
}然后获取代理类的方法就是jdk和cglib代理的逻辑。
4、jdk代理获取代理方法的逻辑
JdkDynamicAopProxy实现了InvocationHandler方法JdkDynamicAopProxy调用其getProxy方法执行目标方法就会执行JdkDynamicAopProxy的invoke方法 OverrideNullablepublic 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 {// 如果接口中没有定义equals()方法那么直接调用不走代理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...// 也是直接调用Advised接口中的方法不走代理逻辑// 其实就是利用代理对象获取ProxyFactory中的信息return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);}Object retVal;// 如果ProxyFactory的exposeProxy为true则将代理对象设置到currentProxy这个ThreadLocal中去// 如果使用EnableAspectJAutoProxy注解需要手动将该参数设置为true默认为falseif (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.// 代理对象在执行某个方法时根据方法筛选出匹配的Advisor并适配成Interceptor 代理链ListObject chain this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);// Check whether we have any advice. If we dont, we can fall back 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.// 如果没有Advice则直接调用对应方法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 cant 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);}}}1getInterceptorsAndDynamicInterceptionAdvice获取拦截器链
// org.springframework.aop.framework.AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice
public ListObject getInterceptorsAndDynamicInterceptionAdvice(Method method, Nullable Class? targetClass) {// 代理对象在执行某个方法时会根据当前ProxyFactory中所设置的Advisor根据当前method再次进行过滤MethodCacheKey cacheKey new MethodCacheKey(method);// 注意这个List表示的就是Advice有缓存。ListObject cached this.methodCache.get(cacheKey);if (cached null) {cached this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(this, method, targetClass);this.methodCache.put(cacheKey, cached);}return cached;
}// org.springframework.aop.framework.DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice
Override
public ListObject getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, Nullable Class? targetClass) {// This is somewhat tricky... We have to process introductions first,// but we need to preserve order in the ultimate list.AdvisorAdapterRegistry registry GlobalAdvisorAdapterRegistry.getInstance();// 从ProxyFactory中拿到所设置的Advice添加时被封装成了DefaultPointcutAdvisor// 添加的时候会控制顺序Advisor[] advisors config.getAdvisors();ListObject interceptorList new ArrayList(advisors.length);Class? actualClass (targetClass ! null ? targetClass : method.getDeclaringClass());Boolean hasIntroductions null;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) {// 如果匹配则将Advisor封装成Interceptor当前Advisor中的Advice可能既是MethodBeforeAdvice也是ThrowingAdvice除了around的都需要包装MethodInterceptor[] interceptors registry.getInterceptors(advisor);if (mm.isRuntime()) { // true 需要包装Interceptor会将参数传过来进行判断// Creating a new object instance in the getInterceptors() method// isnt a problem as we normally cache created chains.for (MethodInterceptor interceptor : interceptors) {interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));}}else {interceptorList.addAll(Arrays.asList(interceptors));}}// 最终interceptorList中存储的是当前正在执行的Method所匹配的MethodInterceptor可能是动态的也可能是非动态的。// 找到Method所匹配的MethodInterceptor后就会开始调用这些MethodInterceptor如果是动态的会额外进行方法参数的匹配判断}}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;
}2包装AfterReturningAdvice、MethodBeforeAdvice为MethodInterceptor
包装的MethodInterceptor和around的效果是一样的。
ThrowsAdviceInterceptor复杂一些会将异常类型匹配出来 3总结
在构造JdkDynamicAopProxy对象时会先拿到被代理对象自己所实现的接口并且额外的增加SpringProxy、Advised、DecoratingProxy三个接口组合成一个Class[]并赋值给proxiedInterfaces属性
并且检查这些接口中是否定义了equals()、hashcode()方法
执行Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this)得到代理对象JdkDynamicAopProxy作为InvocationHandler代理对象在执行某个方法时会进入到JdkDynamicAopProxy的**invoke()**方法中
5、cglib代理获取代理方法的逻辑
CglibAopProxy的getProxy方法逻辑
// org.springframework.aop.framework.CglibAopProxy#getProxy(java.lang.ClassLoader)
Override
public Object getProxy(Nullable ClassLoader classLoader) {if (logger.isTraceEnabled()) {logger.trace(Creating CGLIB proxy: 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;// 如果被代理类本身就已经是cglib所生成的类了if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {// 获取真正的被代理类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, classLoader);// 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.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));// 获取和被代理类所匹配的AdvisorCallback[] callbacks getCallbacks(rootClass);Class?[] types new Class?[callbacks.length];for (int x 0; x types.length; x) {types[x] callbacks[x].getClass();}// fixedInterceptorMap only populated at this point, after getCallbacks call aboveenhancer.setCallbackFilter(new ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));enhancer.setCallbackTypes(types);// Generate the proxy class and create a proxy instance.return createProxyClassAndInstance(enhancer, callbacks);}catch (CodeGenerationException | IllegalArgumentException ex) {throw new AopConfigException(Could not generate CGLIB subclass of this.advised.getTargetClass() : Common causes of this problem include using a final class or a non-visible class,ex);}catch (Throwable ex) {// TargetSource.getTarget() failedthrow new AopConfigException(Unexpected AOP exception, ex);}
}1getCallbacks获取callback方法
// org.springframework.aop.framework.CglibAopProxy#getCallbacks
private Callback[] getCallbacks(Class? rootClass) throws Exception {// Parameters used for optimization choices...boolean isFrozen this.advised.isFrozen();boolean exposeProxy this.advised.isExposeProxy();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 advicetargetInterceptor, // invoke target without considering advice, if optimizednew SerializableNoOp(), // no override for methods mapped to thistargetDispatcher, 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 optimizations 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 CollectionUtils.newHashMap(methods.length);// TODO: small memory optimization here (can skip creation for methods with no advice)for (int x 0; x methods.length; x) {Method method methods[x];ListObject chain this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);fixedCallbacks[x] new FixedChainStaticTargetInterceptor(chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());this.fixedInterceptorMap.put(method, 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;
}// org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor#intercept
Override
Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {Object oldProxy null;boolean setProxyContext false;Object target null;TargetSource targetSource this.advised.getTargetSource();try {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);ListObject chain this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);Object retVal;// Check whether we only have one InvokerInterceptor: that is,// no real advice, but just reflective invocation of the target.if (chain.isEmpty() CglibMethodInvocation.isMethodProxyCompatible(method)) {// 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 invokeMethod(target, method, argsToUse, methodProxy);}else {// We need to create a method invocation...retVal new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();}retVal processReturnType(proxy, target, method, retVal);return retVal;}finally {if (target ! null !targetSource.isStatic()) {targetSource.releaseTarget(target);}if (setProxyContext) {// Restore old proxy.AopContext.setCurrentProxy(oldProxy);}}
}2总结
创建Enhancer对象
设置Enhancer的superClass为通过ProxyFactory.setTarget()所设置的对象的类
设置Enhancer的interfaces为通过ProxyFactory.addInterface()所添加的接口以及SpringProxy、Advised、DecoratingProxy接口
设置Enhancer的Callbacks为DynamicAdvisedInterceptor
最后创建一个代理对象代理对象在执行某个方法时会进入到DynamicAdvisedInterceptor的intercept()方法中
6、执行器链执行逻辑
// org.springframework.aop.framework.ReflectiveMethodInvocation#proceed
Override
Nullable
public Object proceed() throws Throwable {// We start with an index of -1 and increment early.// 当调用完了最后一个interceptor后会就执行被代理方法if (this.currentInterceptorIndex this.interceptorsAndDynamicMethodMatchers.size() - 1) {// 调用目标方法return invokeJoinpoint();}// currentInterceptorIndex 初始值 - 1Object interceptorOrInterceptionAdvice this.interceptorsAndDynamicMethodMatchers.get(this.currentInterceptorIndex);// 当前interceptor是InterceptorAndDynamicMethodMatcher则先进行匹配匹配成功后再调用该Interceptor// 如果没有匹配则递归调用proceed()方法调用下一个interceptorif (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.// 不匹配则执行下一个MethodInterceptorreturn proceed();}}else {// Its an interceptor, so we just invoke it: The pointcut will have// been evaluated statically before this object was constructed.// 直接调用MethodInterceptor传入this在内部会再次调用proceed方法进行递归// 比如MethodBeforeAdviceInterceptorreturn ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);}
}在使用ProxyFactory创建代理对象之前需要往ProxyFactory先添加Advisor
代理对象在执行某个方法时会把ProxyFactory中的Advisor拿出来和当前正在执行的方法进行匹配筛选
把和方法所匹配的Advisor适配成MethodInterceptor
把和当前方法匹配的MethodInterceptor链以及被代理对象、代理对象、代理类、当前Method对象、方法参数封装为MethodInvocation对象
调用MethodInvocation的proceed()方法开始执行各个MethodInterceptor以及被代理对象的对应方法
按顺序调用每个MethodInterceptor的invoke()方法并且会把MethodInvocation对象传入invoke()方法
直到执行完最后一个MethodInterceptor了就会调用invokeJoinpoint()方法从而执行被代理对象的当前方法
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/82928.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!