AOP示例(三续)

使用JDK创建代理有一个限制,即它只能为接口创建代理,这一点我们从Proxy的接口方法newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)就看得很清楚,第三个入参interfaces就是为代理实例指定的实现接口。虽然,面向接口的编程被很多很有影响力人(包括Rod Johnson)的推崇,但在实际开发中,开发者也遇到了很多困惑:难道对一个简单业务表的操作真的需要创建5个类(领域对象类、Dao接口,Dao实现类,Service接口和Service实现类)吗?对于这一问题,我们还是留待大家进一步讨论。现在的问题是:对于没有通过接口定义业务方法的类,如何动态创建代理实例呢?JDK的代理技术显然已经黔驴技穷,CGLib作为一个替代者,填补了这个空缺

下面得演示还是居于上面一直在使用得例子

1.新建CglibProxy代理类

2.修改MethodAdvice类的invoke方法,添加private MethodProxy porxy;这样一个属性,及其set方法

3.修改Test类,改成使用CglibProxy代理

  1. /**
  2.  * 
  3.  */
  4. package com.advice;
  5. import java.lang.reflect.Method;
  6. import net.sf.cglib.proxy.Enhancer;
  7. import net.sf.cglib.proxy.MethodInterceptor;
  8. import net.sf.cglib.proxy.MethodProxy;
  9. /**
  10.  * @author zjb
  11.  *
  12.  */
  13. public class CglibProxy implements MethodInterceptor  {
  14.     
  15.     private MethodAdvice methodAdvice;
  16.     private Enhancer enhancer = new Enhancer();
  17.     public Object getBean(String className){
  18.         try {
  19.             enhancer.setSuperclass(Class.forName(className));
  20.             enhancer.setCallback(this);
  21.             return enhancer.create();
  22.         } catch (Exception e) {
  23.             e.printStackTrace();
  24.         } 
  25.         return null;
  26.     }
  27.     public MethodAdvice getMethodAdvice() {
  28.         return methodAdvice;
  29.     }
  30.     public void setMethodAdvice(MethodAdvice methodAdvice) {
  31.         this.methodAdvice = methodAdvice;
  32.     }
  33.     @Override
  34.     public Object intercept(Object object,  Method method, Object[] args,
  35.             MethodProxy porxy) throws Throwable {
  36.         methodAdvice.setArgs(args);
  37.         methodAdvice.setMethod(method);
  38.         methodAdvice.setPos(-1);
  39.         methodAdvice.setDone(false);
  40.         methodAdvice.setTarget(object);
  41.         methodAdvice.setPorxy(porxy);
  42.         return methodAdvice.proceed();
  43.     }
  44. }
修改以后的MethodAdvice类的invoke方法

 

  1. private Object invoke(){
  2.         done=true;
  3.         try {
  4.             if(porxy!=null){
  5.                 return porxy.invokeSuper(target, args);
  6.             }else{
  7.                 return method.invoke(target, args);
  8.             }
  9.         } catch (Exception e) {
  10.             e.printStackTrace();
  11.         } catch (Throwable e) {
  12.             e.printStackTrace();
  13.         } 
  14.         return null;
  15.     }

 

  1. package com.myadvice.test;
  2. import com.advice.CglibProxy;
  3. import com.advice.DynaProxy;
  4. import com.advice.MethodAdvice;
  5. import com.test.BookBiz;
  6. import com.test.BookBizImpl;
  7. public class Test {
  8.     /**
  9.      * @param args
  10.      */
  11.     public static void main(String[] args) {
  12. //      DynaProxy proxy= new DynaProxy();
  13.         CglibProxy proxy= new CglibProxy();
  14.         MethodAdvice methodAdvice= new MethodAdvice();
  15.         methodAdvice.AddAdvice(new Object[]{new MyAdvice()});
  16.         proxy.setMethodAdvice(methodAdvice);
  17. //      BookBiz bookBiz=(BookBiz)proxy.getBean(BookBizImpl.class.getName());
  18.         BookBizImpl bookBiz=(BookBizImpl)proxy.getBean(BookBizImpl.class.getName());
  19.         bookBiz.buy("张三""Spring深入潜出"50); 
  20.         bookBiz.comment("李四""《恐怖世界》一点都不恐怖,很好看!"); 
  21.         bookBiz.comment("张三""《Spring深入潜出》还是写得不错的!");
  22.     }
  23. }

下面是运行结果:

[环绕通知]
前通知,调用的方法:buy,参数:[张三, Spring深入潜出, 50.0]
业务方法buy开始执行
·张三购买图书:Spring深入潜出
·张三增加积分:5
·向物流系统下发货单
业务方法buy结束
后通知,调用的方法:buy,参数:[张三, Spring深入潜出, 50.0]
[环绕通知]
屏蔽李四所有的评论
[环绕通知]
前通知,调用的方法:comment,参数:[张三, 《Spring深入潜出》还是写得不错的!]
业务方法comment开始执行
·张三发表书评《Spring深入潜出》还是写得不错的!
业务方法comment结束
后通知,调用的方法:comment,参数:[张三, 《Spring深入潜出》还是写得不错的!]

 

通过学习AOP,俺们现在回去想想Spring的数据库事务自动管理是怎么实现的,就比较清晰了,应该使用了环绕通知,在proceed之前开始一个事务,然后在提交事务,就这么简单而已。(^_^,大功告成,关于aop打完收工)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值