是这样的 一般aop的处理 都是以调用链的形式处理的、
如
Java代码
RemoteInvocation invocation = new RemoteInvocation();
invocationsetMethodName(tgetMethod()getName());
invocationsetParameterTypes(tgetMethod()getParameterTypes());
invocationsetArguments(tgetArguments());
invocationaddAttribute(
>
在Spring的AOP模块,一个主要的部分是代理对象的生成,可以通过ProxyFactoryBean来完成,它封装了主要代理对象的生成过程。在这个生成过程中,可以使用JDK的Proxy和CGLIB两种生成情况。
Tip: 什么是匿名类
即没有名称的类,其名称由Java编译器给出,一般为:外部类名称+$+匿名类顺序,名称也就是其他地方不能引用,不能实例化,只用一次,当然也就不能有构造器。
在ProxyFactoryBean中,需要为target目标对象生成Proxy代理对象,从而为AOP横切面的编织做好准备。从FactoryBean中获取对象,是以getObject()方法作为入口完成的。在该方法中,首先对通知器链进行初始化,封装了一系列的拦截器,这些拦截器都要从配置中读取,然后为代理对象的生成做好准备。在生成代理对象时,因为Spring中有singleton类型和prototype类型这两种不同的Bean,所以要对代理对象的生成做一个区分。
首先为Proxy代理对象配置Advisor链,在initializeAdvisorChain()方法中执行。
在该方法中它会首先通过thisadvisorChainInitialized来判断通知器链是否已经初始化了,如果已经初始化了,就直接返回。其他情况下,通过 thisinterceptorNames 来要添加的通知器名,然后通过该名从IOC容器中取得的通知器加入到拦截器链中。
生成singleton的代理对象在getSingletonInstance()中完成
如果它还没有被创建,则lazily creating
在Spring代理目标target时,其实并不是直接创建一个目标target的对象实例的,而是通过一个TargetSource类型的对象对目标target进行封装,Spring Aop获取目标对象始终是通过 TargetSourcegetTarget() 方法进行的。
proxy(代理对象)代理的不是target,而是TargetSource
那么问题来了:为什么SpringAOP代理不直接代理target,而需要通过代理TargetSource(target的来源,其内部持有target),间接代理target呢
通常情况下,一个proxy(代理对象)只能代理一个target,每次方法调用的目标也是唯一固定的target。但是,如果让proxy代理TargetSource,可以使得每次方法调用的target实例都不同(当然也可以相同,这取决于TargetSource实现)。这种机制使得方法调用变得灵活,可以扩展出很多高级功能,如:target pool(目标对象池)、hot swap(运行时目标对象热替换),等等。
Spring内置了多种TargetSource
监听调用AdvisedSupportListener实现类的activated方法
具体的代理对象的生成,是在ProxyFactoryBean的基类AdvisedSupport的实现中借助AopProxyFactory完成的,这个代理对象要么从JDK中生成,要么借助CGLIB获得。
这个AopProxyFactory是在初始化函数中定义的,使用的是DefaultAopProxyFactor。
如果targetClass是接口类,使用JDK来生成Proxy
如果不是接口类要生成Proxy,那么使用CGLIB来生成。
接下来分别介绍两种不同的方式来产生AopProxy代理对象
首先从advised对象中取得代理对象的代理接口配置,然后调用Proxy的newProxyInstance方法,得到最终的Proxy代理对象。
在生成代理对象时,需要指明三个参数,类加载器,代理接口和Proxy回调方法所在的对象。
在回调方法所在对象中,需要实现InvocationHandler接口,它定义了invoke方法,
对于JdkDynamimcAopProxy,它本身实现了InvocationHandler接口和invoke方法,这个invoke方法是Proxy代理对象的回调方法。
在该篇文章中就不讲解了,感兴趣的可以百度搜索。
注:本文大多数是对《Spring技术内幕》的阅读整理。
@Component
public class TestInterceptor {
@Pointcut("execution ( comtestfacade())")
public void testPointcut(){}
@Around("testPointcut()")
public Object testHandleBody(ProceedingJoinPoint pjp) throws Throwable{
Object retVal = null; //连接点方法返回值
//获取将要执行的方法名称
String methodName = pjpgetSignature()getName();
//获取执行方法的参数
Object[] args = pjpgetArgs();
title: Spring之AOP二
date: 2017-03-25 02:42:16
tags:
execution
日常使用最多的标识符,使用execution标识符的Pointcut表达式格式:
within
指定类型,类型下所有方法。可以使用 和 扩展,like: within(tkzhanghspring)
this和target
Spring中使用this和target实际作用类似
args
指定参数类型,指定参数数量
与execution标识符不同,args标识符会在运行期间动态检查参数类型
@within
指定类型,类型下的所有方法,要求类型标记了指定注解,like:
@target
指定标记了给定注解类型的目标对象的所有方法
@args
指定参数类型,要求参数参数类型标记了指定注解
@annotation
指定标记了指定注解的方法,@Transctional的实现方式
所有@AspectJ形式声明的这些Pointcut表达式最终都会转化成Pointcut的具体实现。
AspectJExpressionPointcut如同他的名字面向AspectJ的pointcut实现,整个继承体系:
使用@Aspect注解标记的类中,具体的Advice形式由具体的Advice注解标示。
注解的方法中需要访问上下文信息最主要的方式:将方法的第一个参数声明为JoinPoint类型
以事务为例,事务管理也是使用AOP,具体是@annotation形式的Pointcut声明(这样我就不用声明Advice了)
当在aFun内调用bFun时事务没有开启,也就是AOP没有生效,原因:
我们期望虚线的调用方式,实际上调用时红色的路线,添加在代理对象上的AOP逻辑在嵌套调用时根本没有机会触发。在事务处理时尤其要注意避免这样的嵌套调用问题。
解决:
不管是那种方式都要注入相关Bean,具体那种更优雅由你来决定了。
以上就是关于Spring AOP implements MethodInterceptor 要怎么传参数进来全部的内容,包括:Spring AOP implements MethodInterceptor 要怎么传参数进来、aop30怎么从电脑上下参数、Spring AOP之AopProxy代理对象等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)