AOP 学习, ProxyFactory 学习二
程序员文章站
2022-04-25 20:22:47
...
ProxyFactory: 拦截具有接口的类
//通过setInterfaces()方法可以明确告知ProxyFactory,我们要对ITask接口类型进行代理。
如果目标类实现了至少一个接口,不管我们有没有通过ProxyFactory的setInterfaces()方法明确指定要对特定的接口类型进行代理,只要不将ProxyFactory的optimize和ProxyTargetClass两个属性的值设置为true,那么ProxyFactory都会按照面向接口进行代理。
pf.setOptimize(true);
pf.setProxyTargetClass(true);
下面的代码和上面的代码输出结果是一样的
注意如果是基于接口进行代理的, 那么在最后从带来得到的类pf.getProxy(), 强制转化时, 必须是转化成接口类型的,
[color=red]TaskImpl task=(TaskImpl)pf.getProxy(); 这样是不允许的, 会抛出错误[/color]
如何强制使用CGLIB对具有接口的类进行代理呢, 只需要添加更换下面的代码
结果
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
上一篇: Spring AOP 日志记录
下一篇: js 各种循环使用