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