欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

AOP 学习, ProxyFactory 学习二

程序员文章站 2022-04-25 20:22:47
...
ProxyFactory: 拦截具有接口的类



public interface ITask {

public void execute();

}

public class TaskImpl implements ITask {

@Override
public void execute() {

System.out.println("run code to here");

}

}


import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class MessageDecorator implements MethodInterceptor{

public Object invoke(MethodInvocation invocation) throws Throwable{
System.out.print("hello\n");
Object retVal=invocation.proceed();
System.out.print("end");
return retVal;
}

}


//通过setInterfaces()方法可以明确告知ProxyFactory,我们要对ITask接口类型进行代理。


import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.NameMatchMethodPointcutAdvisor;
public class test2 {

public static void main(String[] args) {

TaskImpl target =new TaskImpl();

ProxyFactory pf=new ProxyFactory(target);

//pf.setInterfaces(Class[] interfaces) 函数原型
pf.setInterfaces(new Class[]{ITask.class});
//通过setInterfaces()方法可以明确告知ProxyFactory,我们要对ITask接口类型进行代理。


NameMatchMethodPointcutAdvisor advisor = new NameMatchMethodPointcutAdvisor();

advisor.setMappedName("execute"); //切点

advisor.setAdvice(new MessageDecorator()); //切面, 拦截时要执行的动作

pf.addAdvisor(advisor);

ITask task=(ITask)pf.getProxy();

task.execute();

}
}




如果目标类实现了至少一个接口,不管我们有没有通过ProxyFactory的setInterfaces()方法明确指定要对特定的接口类型进行代理,只要不将ProxyFactory的optimize和ProxyTargetClass两个属性的值设置为true,那么ProxyFactory都会按照面向接口进行代理。

pf.setOptimize(true);
pf.setProxyTargetClass(true);

下面的代码和上面的代码输出结果是一样的


public static void main(String[] args) {

TaskImpl target =new TaskImpl();

ProxyFactory pf=new ProxyFactory(target);

NameMatchMethodPointcutAdvisor advisor = new NameMatchMethodPointcutAdvisor();

advisor.setMappedName("execute");

advisor.setAdvice(new MessageDecorator());

pf.addAdvisor(advisor);

ITask task=(ITask)pf.getProxy();

task.execute();

}



注意如果是基于接口进行代理的, 那么在最后从带来得到的类pf.getProxy(), 强制转化时, 必须是转化成接口类型的,


[color=red]TaskImpl task=(TaskImpl)pf.getProxy(); 这样是不允许的, 会抛出错误[/color]

如何强制使用CGLIB对具有接口的类进行代理呢, 只需要添加更换下面的代码


pf.setProxyTargetClass(true); // add this line

ITask task=(ITask)pf.getProxy();

//TaskImpl task=(TaskImpl)pf.getProxy(); // this line also works now

System.out.println(task.getClass());



结果


class TaskImpl$$EnhancerByCGLIB$$67d0dc43
hello
run code to here
end
相关标签: AOP