您的位置:首页 > 新闻 > 热点要闻 > 海南黄页电话号码_中国十大奇迹工程_徐州百度推广总代理_站长之家查询工具

海南黄页电话号码_中国十大奇迹工程_徐州百度推广总代理_站长之家查询工具

2024/10/11 4:11:38 来源:https://blog.csdn.net/sinat_32502451/article/details/142589710  浏览:    关键词:海南黄页电话号码_中国十大奇迹工程_徐州百度推广总代理_站长之家查询工具
海南黄页电话号码_中国十大奇迹工程_徐州百度推广总代理_站长之家查询工具

AOP基础知识

AOP基础知识,详情见: https://blog.csdn.net/sinat_32502451/article/details/142291052

AOP 源码,详情见: https://blog.csdn.net/sinat_32502451/article/details/142291110

ProceedingJoinPoint

在上面的示例中,运用到了 ProceedingJoinPoint 。

ProceedingJoinPoint 是继承 JoinPoint(连接点) 的类。
从以上示例代码看出, ProceedingJoinPoint拥有 JoinPoint(连接点)的特性,
可以获取类的信息,包括类名、方法名、参数等(joinPoint.getArgs()),
还可以执行目标对象方法的逻辑(joinPoint.proceed())。

代码: org.aspectj.lang.ProceedingJoinPoint

/***   ProceedingJoinPoint 继承 JoinPoint(连接点) .*   ProceedingJoinPoint 公开了progress(..)方法,以支持@AJ aspects.**/
public interface ProceedingJoinPoint extends JoinPoint {/***  joinpoint需要知道它的AroundClosure,以便proceed可以委托给closure.run()* */void set$AroundClosure(AroundClosure arc);/*** 继续下一个advice或目标方法调用**/public Object proceed() throws Throwable;/*** 继续下一个advice或目标方法调用**/public Object proceed(Object[] args) throws Throwable;}

ReflectiveMethodInvocation的proceed

不管是 @Pointcut 还是 @Around(环绕通知,包含前置和后置两个) 都会调用这个 proceed 方法。

代码: org.springframework.aop.framework.ReflectiveMethodInvocation#proceed

    @Override@Nullablepublic Object proceed() throws Throwable {if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {//以下会调用 Joinpoint(连接点) // 通过 invokeJoinpoint 的调用, 可以拿到目标方法的返回值。 //注意: 这里的 invokeJoinpoint() 调用的是 // org.springframework.aop.framework.CglibAopProxy.CglibMethodInvocation#invokeJoinpoint//并不是自身的 invokeJoinpoint()方法。return invokeJoinpoint();}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 {return proceed();}}else {// 拦截器调用方法。@Around 环绕通知的前置和后置都会走这里return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);}}

CglibAopProxy.CglibMethodInvocation

调用 joinPoint.proceed(); 这一行代码后,最后会调用这里的 Cglib 动态代理。

Cglib 动态代理,调用连接点的方法。

通过 invokeJoinpoint 的调用, 可以拿到目标方法的返回值。

代码: org.springframework.aop.framework.CglibAopProxy.CglibMethodInvocation#invokeJoinpoint

    private static class CglibMethodInvocation extends ReflectiveMethodInvocation {private final MethodProxy methodProxy;private final boolean publicMethod;public CglibMethodInvocation(Object proxy, @Nullable Object target, Method method,Object[] arguments, @Nullable Class<?> targetClass,List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);this.methodProxy = methodProxy;this.publicMethod = Modifier.isPublic(method.getModifiers());}/*** 调用 JoinPoint(连接点) 的方法*/@Overrideprotected Object invokeJoinpoint() throws Throwable {if (this.publicMethod) {// 通过这里的调用, 可以拿到目标方法的返回值。return this.methodProxy.invoke(this.target, this.arguments);}else {return super.invokeJoinpoint();}}}

CglibAopProxy.DynamicAdvisedInterceptor

代码: org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor

调用 JoinPoint(连接点) 的方法后,会进行后置通知,调用 CglibAopProxy.DynamicAdvisedInterceptor。

    /*** 通用AOP回调。当目标是动态的或代理未冻结时使用。**/private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {private final AdvisedSupport advised;public DynamicAdvisedInterceptor(AdvisedSupport advised) {this.advised = advised;}@Override@Nullablepublic 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) {oldProxy = AopContext.setCurrentProxy(proxy);setProxyContext = true;}target = targetSource.getTarget();Class<?> targetClass = (target != null ? target.getClass() : null);List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);Object retVal;// 这里面的逻辑,重点看看。// 检查是否没有真正的advice,只是对目标的反射调用。if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {// 我们可以跳过创建 MethodInvocation:直接调用目标。Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);retVal = methodProxy.invoke(target, argsToUse);}else {// 创建一个方法调用。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) {AopContext.setCurrentProxy(oldProxy);}}}

调用的方法栈:

这些代码也可以看看。

processReturnType:394, CglibAopProxy (org.springframework.aop.framework)
access$000:84, CglibAopProxy (org.springframework.aop.framework)
intercept:690, CglibAopProxy$DynamicAdvisedInterceptor (org.springframework.aop.framework)
getValue:-1, TestController$$EnhancerBySpringCGLIB$$682df634 (com.example.demo.controller)
invoke:-1, GeneratedMethodAccessor68 (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:497, Method (java.lang.reflect)
doInvoke:209, InvocableHandlerMethod (org.springframework.web.method.support)
invokeForRequest:136, InvocableHandlerMethod (org.springframework.web.method.support)
invokeAndHandle:102, ServletInvocableHandlerMethod (org.springframework.web.servlet.mvc.method.annotation)
invokeHandlerMethod:891, RequestMappingHandlerAdapter (org.springframework.web.servlet.mvc.method.annotation)
handleInternal:797, RequestMappingHandlerAdapter (org.springframework.web.servlet.mvc.method.annotation)
handle:87, AbstractHandlerMethodAdapter (org.springframework.web.servlet.mvc.method)
doDispatch:991, DispatcherServlet (org.springframework.web.servlet)
doService:925, DispatcherServlet (org.springframework.web.servlet)
processRequest:974, FrameworkServlet (org.springframework.web.servlet)
doGet:866, FrameworkServlet (org.springframework.web.servlet)
service:635, HttpServlet (javax.servlet.http)
service:851, FrameworkServlet (org.springframework.web.servlet)
service:742, HttpServlet (javax.servlet.http)
internalDoFilter:231, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:52, WsFilter (org.apache.tomcat.websocket.server)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilterInternal:99, RequestContextFilter (org.springframework.web.filter)
doFilter:107, OncePerRequestFilter (org.springframework.web.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilterInternal:109, HttpPutFormContentFilter (org.springframework.web.filter)
doFilter:107, OncePerRequestFilter (org.springframework.web.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilterInternal:93, HiddenHttpMethodFilter (org.springframework.web.filter)
doFilter:107, OncePerRequestFilter (org.springframework.web.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilterInternal:200, CharacterEncodingFilter (org.springframework.web.filter)
doFilter:107, OncePerRequestFilter (org.springframework.web.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
invoke:198, StandardWrapperValve (org.apache.catalina.core)
invoke:96, StandardContextValve (org.apache.catalina.core)
invoke:493, AuthenticatorBase (org.apache.catalina.authenticator)
invoke:140, StandardHostValve (org.apache.catalina.core)
invoke:81, ErrorReportValve (org.apache.catalina.valves)
invoke:87, StandardEngineValve (org.apache.catalina.core)
service:342, CoyoteAdapter (org.apache.catalina.connector)
service:800, Http11Processor (org.apache.coyote.http11)
process:66, AbstractProcessorLight (org.apache.coyote)
process:806, AbstractProtocol$ConnectionHandler (org.apache.coyote)
doRun:1498, NioEndpoint$SocketProcessor (org.apache.tomcat.util.net)
run:49, SocketProcessorBase (org.apache.tomcat.util.net)
runWorker:1142, ThreadPoolExecutor (java.util.concurrent)
run:617, ThreadPoolExecutor$Worker (java.util.concurrent)
run:61, TaskThread$WrappingRunnable (org.apache.tomcat.util.threads)
run:745, Thread (java.lang)

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com