读书人

AOP 学习, ProxyFactory 学习2

发布时间: 2012-08-24 10:00:21 作者: rapoo

AOP 学习, ProxyFactory 学习二
ProxyFactory: 拦截具有接口的类

public interface ITask {public void execute();}public class TaskImpl implements ITask {@Overridepublic 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(), 强制转化时, 必须是转化成接口类型的,


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

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

pf.setProxyTargetClass(true); // add this lineITask task=(ITask)pf.getProxy();//TaskImpl task=(TaskImpl)pf.getProxy(); // this line also works nowSystem.out.println(task.getClass());


结果

class TaskImpl$$EnhancerByCGLIB$$67d0dc43hellorun code to hereend





读书人网 >软件架构设计

热点推荐