<span style="font-family:KaiTi_GB2312;font-size:18px;"><strong>Spring AOP的实现机制
动态代理
(1)静态代理
举例说明如下:
ISubject 该接口是对被访问者或被访问资源的抽象。
SubjectImpl 被访问者或者被访问资源的具体实现,如果你要访问某位明星,SubjectImpl就是你想访问的明星
SubjectProxy 被访问者或者被访问资源的代理实现类,该类持有一个ISubject接口的具体实例。在这个场景中,我们要对SubjectImpl进行代理,那么SubjectProxy现在
持有的就是SubjectImpl的实例。
public class SubjectProxy implements ISubject{
private ISubject subject;
public String request(){
//add pre-process logic if necessary
String originalResult=subject.request();
//add post process logic if necessary
return "proxy:" +originalResult
}
public ISubject getSubject(){
return subject;
}
public void setSubject(ISubject subject){
this.subject=subject;
}
}
public class SubjectImpl implements ISubject{
public String request(){
//process logic
return "OK";
}
}
这里SubjectImpl和SubjectProxy都实现了相同的接口ISubject ,SubjectProxy内部持有SubjectImpl的引用。
在将请求转发给被代理对象SubjectImpl之前或者之后,都可以根据情况插入其他处理逻辑。如果SubjectImpl
是系统中的Joinpoint所在的对象,即目标对象,那么就可以为这个目标对象创建一个代理对象,然后将横切
逻辑添加到这个代理对象中。当系统使用这个代理对象运行的时候,原有逻辑的实现和横切逻辑就完全融合到
一个系统中。
然后将代理对象绑定到系统中的实现代码如下:
ISubject target=new ISubjectImpl();
ISubject fianlSubject =new SubjectProxy(target);
fianlSubject.request();
上面属于静态代理,对于多个具有resquest方法的类,我们要为其织入相同的逻辑时又得重新实现一个代理对象,
所以说静态代理原理上是可行的,但是存在其他问题。
(2)动态代理
使用动态代理机制,可以为指定的接口在系统运行期间动态生成代理对象。
动态代理机制的实现主要由一个类和一个接口组成,即java.lang.reflect.Proxy和java.lanf.reflect.InvocationHandler接口
虽然要为ISubject和IRequestable两种类型提供代理对象,但因为代理对象中药添加的横切逻辑时一样的,所以我们
只需要实现一个InvocationHandler就可以了。
简单的实现代码如下:
public class RequestableInvocationHandler implements InvocationHandler{
private Object target;
public RequestableInvocationHandler(Object target){
this.target=target;
}
public Object invoke(Object proxy,Method method,Object[]args)throws Throwable{
if(method.getName().equals("request"))
{
//aspect
}
return method.invoke(target,args);
}
return null;
}
然后我们就可以使用Proxy类,根据RequestableInvocationHandler的逻辑,为ISubject和IRequestable两种类型生成相应的代理对象实例
ISubject subject=(ISubject)Proxy.newProxyInstance(Subject.class.getClassLoader(),new Class[]{ISubject.class},new RequestableInvocationHandler(new SubjectImpl()));
subject.request();
IRequestable requestable=(IRequestable)Proxy.newProxyInstance(IRequestable.class.getClassLoader(),new Class[]{IRequestable.class},new RequestableInvocationHandler(new RequestableImpl()));
requestable.request();
InvocationHandler就是我们实现横切逻辑的地方,它是横切逻辑的载体,作用和Advice一样。所以在使用动态代理机制实现AOP的过程
中,我们可以在InvocationHandler的基础上细化程序结构,并根据Advice的类型,分化出对应不同Advice类型的程序结构。
动态代理虽好,但是不能满足所有需求。因为动态代理机制只能对实现了相应Interface的类使用,如果某个类没有实现任何的Interface
就无法使用动态代理为其生成相应的动态代理对象
默认情况下,如果Spring AOP发现目标对象实现了相应Interface,则采用动态代理机制为其生成代理对象实例。而如果目标对象没有实现任何Interface,Spring AOP 会尝试使用CGLIB
(Code Genaration Library)的开源的动态字节码生成类库,为目标对象动态生成代理对象
定义目标类如下:
pubic class Requestable{
public void request(){
System.out.println("rq in Requestable without implement any interface");
}
}
要对Requestable类进行扩展,首先需要实现一个net.sf.cglib.proxy.Callback。不过更多的时候我们直接使用net.sf.cglib.proxy.MethodInterceptor接口
public class RequestCtrlCallback implements MethodInterceptor{
public Object intercept(Object object,Method method,Object[]args,MethodProxy proxy)throws Throwable{
if(method.getName.equals("request")){
//process logic;
return proxy.invokeSuper(object,args);
}
}
}
这样,RequestableCallback就实现了对request()方法请求进行访问控制的逻辑。现在通过CGLIB的Enhancer为目标对象动态生成一个子类,
并将RequestableCallback中的横切逻辑附加到该子类中.
Enhancer enchaner=new Enhancer();
enchaner.setSuperclass(Requestable.class);
enchaner.setCallback(new RequestableCallback());
Requestable proxy =(Requestable)enchaner.create();
proxy.request();
</strong></span>
还没有评论,来说两句吧...