免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1020 | 回复: 0
打印 上一主题 下一主题

深入浅出 spring AOP [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-11-24 09:19 |只看该作者 |倒序浏览

先不讨论AOP的各种名词,也不作各种AOP的比较,我将在例子中介绍各种名词。
1。先写一个javabean,就是target object。
package org.tatan.test;
public class MessageBean {
  public void write() {
         System.out.print("AOP example");
     }
}
2。写一个AOP的advice类
MethodInterceptor是AOP联盟的标准接口,它是最简单最实用的连接点(joinpoint),实现了around advice ,你可以在他返回前调用target的方法。
package org.tatan.test;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MessageCode implements MethodInterceptor {
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.print("this is a ");
        Object returnValue = invocation.proceed();
        
        return returnValue ;
    }
}
3。把MessageCode advice weave 到proxy factory,proxy factory是整个架构的核心
先创建instance of MessageBean,然后创建代理的instance ,MessageCode advice 传递给的
addAdvice()方法,设置Target Object,调用getProxy()产生代理对象。
import org.springframework.aop.framework.ProxyFactory;
public class AOPExample {
  public static void main(String[] args) {
         MessageBean target = new MessageBean();
         
         
         ProxyFactory pf = new ProxyFactory();
     
         pf.addAdvice(new MessageCode());
         pf.setTarget(target);
     
         MessageBean proxy = (MessageBean) pf.getProxy();
         
         //输出原始信息
         target.write();
        //输出代理对象调用的信息
         proxy.write();
     }
}
4。classpath中加入cglib-nodep-2.1_2.jar ,spring.jar,aopalliance.jar,commons-logging.jar
结果
AOP example
this is a AOP example
有人问我,为什末使用CGLIB proxy而不使用JDK Dynamic Proxies,这和spring aop使用的原则相关。
1.使用AOP的时候,尽可能的使用接口,而不是使用具体的类,这样就可以使用JDK Dynamic Proxies,
如果目标类没有实现接口,spring使用CGLIB生成目标类的子类。
下面给个例子
接口类
package org.tatan.test;
    public interface Worker {
        void doSomeWork(int numOfTimes);
    }
   
目标类
package org.tatan.test;
public class WorkerBean implements Worker {
    public void doSomeWork(int numOfTimes) {
        for (int i = 0; i             System.out.println("---->" + args);
        }
        System.out.println();
      
        return returnValue;
    }
}
运行
package org.tatan.test;
import org.springframework.aop.framework.ProxyFactory;
public class AOPExample2 {
    public static void main(String[] args) {
        Worker bean = getWorkerBean();
        bean.doSomeWork(100000000);
    }
    private static Worker getWorkerBean() {
        WorkerBean target = new WorkerBean();
        ProxyFactory pf = new ProxyFactory();
        pf.setTarget(target);
        pf.addAdvice(new AroundAdvice());
        pf.setInterfaces(new Class[]{Worker.class});
        return (Worker) pf.getProxy();
    }
}
如果调用了setInterfaces();[color="#000000"]就不要cglib了,使用[color="#000000"]JDK Dynamic Proxies,[color="#000000"]只是使用JDK Dynamic Proxies程序执行的效率比较低。
使用CGLIB的Frozen效率比标准的CGLIB效率高。
package org.tatan.test;
import org.springframework.aop.framework.ProxyFactory;
public class AOPExample2 {
    public static void main(String[] args) {
        Worker bean = getWorkerBean();
        bean.doSomeWork(100000000);
    }
    private static Worker getWorkerBean() {
        WorkerBean target = new WorkerBean();
        ProxyFactory pf = new ProxyFactory();
        pf.setTarget(target);
        pf.addAdvice(new AroundAdvice());
     //  pf.setInterfaces(new Class[]{Worker.class});
       pf.setFrozen(true);
[color="#000000"]        return (Worker) pf.getProxy();
    }
}
原则上使用CGLIB,因为既可以使用类,还可以使用接口,JDK proxy 只能代理口[color="#000000"]。
[color="#000000"]2.目标类的方法不能是final的,因为spring要生成目标类的子类,任何要advised的方法都要overide,所以不允许final method。


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/11783/showart_58443.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP