springframe(七)AOP之动态代理
2016-07-29 00:00
489 查看
AOP的原理就是动态代理,上一片介绍了什么是代理,展示了静态代理,很多时候静态代理还是不太灵活的,我们需要动态代理来完成我们的业务逻辑,这里展示下动态代理的创建,并通过代码的注释告诉你,为啥“java的事务是基于代理的”
1、创建我们的接口,还是上次的IHello接口
2、创建我们的接口实现类。
3、创建一个实现了动态代理必备参数InvocationHandler接口的实现类。这个是我们整个动态代理的核心点。我们所有的文章都在这个地方下功夫,但是具体如何使用实现这个接口的类,那还要等下一步才能解释了。
闲着没事看一下上边的日志标注,我们的动态代理的核心点就是上边的方法,我输出日志的地方,就是一些额外的附加业务逻辑的最好切入点
4、将我们的实现类绑定到动态代理上。如果将动态代理实现
这里就是我们动态代理的创建了,我们将要代理的对象绑定到动态代理上,而动态代理要那个实现了InvocationHandler接口的方法类的invoke执行。那我们只能在那个invoke中做文章了。
5、开启我们的测试类
测试下我们动态代理是否可用:
6、测试日志结果:
绑定操作的输出值:interface com.itcast.aop.IHello
2009-3-15 11:29:38 com.itcast.aop.LogHandler invoke
信息: 看日志输出,被调用的方法名称是可以被输出的,你可以对所有的方法名做比对,做不同处理
2009-3-15 11:29:38 com.itcast.aop.LogHandler invoke
信息: 开始我们的方法 ...public abstract void com.itcast.aop.IHello.hello(java.lang.String) throws java.lang.Exception
2009-3-15 11:29:38 com.itcast.aop.LogHandler invoke
信息: 如果你想做一个事务控制,这个地方是再好不过的地方了,开始你的事务?
Hello2 :hello 动态代理的输入参数
InvocationHandler实现类中输出传入的参数值:动态代理的输入参数
2009-3-15 11:29:38 com.itcast.aop.LogHandler invoke
信息: 在这里结束你的事务!java的事务是基于代理的,这下你明白了吗?
2009-3-15 11:29:38 com.itcast.aop.LogHandler invoke
信息: 结束我们的方法...public abstract void com.itcast.aop.IHello.hello(java.lang.String) throws java.lang.Exception
上边的日志说明了我们可以输出的地方,可以做动作的位置
6、总结下
什么是aop,明白了没?解释起来就是“面向切面编程”,动态代理就是一把刀子,在你的程序调用的过程中切来切去。原理就是上边的动态代理。不过spring给我们封装了一下,用cglib这个jar来动态的帮我们生成每个实现类的动态代理,spring的事务控制之类的东西都是基于这个的。总的来说大家不要被穿在java外部的马甲给迷惑住了。事情的原理就是上边那个。
1、创建我们的接口,还是上次的IHello接口
package com.itcast.aop; //要实现的接口 public interface IHello { public void hello(String name) throws Exception; public void helloAaa(String name); public void helloBbb(String name); }
2、创建我们的接口实现类。
package com.itcast.aop; //实现方法,用来展示我们的动态代理 public class HelloSpeaker2 implements IHello { public void hello(String name) { System.out.println("Hello2 :hello "+name); } public void helloAaa(String name) { System.out.println("Hello2 in aaa"+ name); } public void helloBbb(String name) { System.out.println("Hello2 in bbb"+ name); } }
3、创建一个实现了动态代理必备参数InvocationHandler接口的实现类。这个是我们整个动态代理的核心点。我们所有的文章都在这个地方下功夫,但是具体如何使用实现这个接口的类,那还要等下一步才能解释了。
package com.itcast.aop; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.logging.Logger; //操作代理类的任何一个方法都会触发这个invoke操作 public class LogHandler implements InvocationHandler { private Logger logger = Logger.getLogger(this.getClass().getName()); private Object delegate; public LogHandler(Object obj){ this.delegate=obj; } public Object invoke(Object proxy, Method method, Object[] arg2) throws Throwable { Object result = null; try{ //看日志输出,被调用的方法名称是可以被输出的,你可以对所有的方法名做比对,做不同处理 logger.info("看日志输出,被调用的方法名称是可以被输出的,你可以对所有的方法名做比对,做不同处理"); logger.info("开始我们的方法 ..."+method); //如果你想做一个事务控制,这个地方是再好不过的地方了,开始你的事物? logger.info("如果你想做一个事务控制,这个地方是再好不过的地方了,开始你的事务?"); result = method.invoke(delegate, arg2); for(Object tmp:arg2){ System.out.println("InvocationHandler实现类中输出传入的参数值:"+tmp.toString()); } //在这里结束你的事务!java的事务是基于代理的,这下你明白了吗? logger.info("在这里结束你的事务!java的事务是基于代理的,这下你明白了吗?"); logger.info("结束我们的方法..."+method); }catch(Exception e){ e.printStackTrace(); } return result; } }
闲着没事看一下上边的日志标注,我们的动态代理的核心点就是上边的方法,我输出日志的地方,就是一些额外的附加业务逻辑的最好切入点
4、将我们的实现类绑定到动态代理上。如果将动态代理实现
package com.itcast.aop; //绑定操作,将指定的类通过反射生成动态代理 import java.lang.reflect.Proxy; public class Bind { public Object bind(Object delegate){ //输出的是接口的全路径名称 System.out.println("绑定操作的输出值:"+delegate.getClass().getInterfaces()[0]); /**通过反射生成动态代理,这里的LogHandler类是实现了InvocationHandler接口的类, *实现InvocationHandler接口类在北Proxy作为参数调用的时候,会调用接口中的invoke *方法,我们可以在invoke方法的内部进行我们的附加操作**/ return Proxy.newProxyInstance(delegate.getClass().getClassLoader(), delegate.getClass().getInterfaces(), new LogHandler(delegate)); } }
这里就是我们动态代理的创建了,我们将要代理的对象绑定到动态代理上,而动态代理要那个实现了InvocationHandler接口的方法类的invoke执行。那我们只能在那个invoke中做文章了。
5、开启我们的测试类
测试下我们动态代理是否可用:
package com.itcast.aop; //动态代理类的测试方法 public class Main { public static void main(String[] args) { Bind b = new Bind(); IHello helloProxy = (IHello)b.bind(new HelloSpeaker2()); try { helloProxy.hello("动态代理的输入参数"); } catch (Exception e) { e.printStackTrace(); } } }
6、测试日志结果:
绑定操作的输出值:interface com.itcast.aop.IHello
2009-3-15 11:29:38 com.itcast.aop.LogHandler invoke
信息: 看日志输出,被调用的方法名称是可以被输出的,你可以对所有的方法名做比对,做不同处理
2009-3-15 11:29:38 com.itcast.aop.LogHandler invoke
信息: 开始我们的方法 ...public abstract void com.itcast.aop.IHello.hello(java.lang.String) throws java.lang.Exception
2009-3-15 11:29:38 com.itcast.aop.LogHandler invoke
信息: 如果你想做一个事务控制,这个地方是再好不过的地方了,开始你的事务?
Hello2 :hello 动态代理的输入参数
InvocationHandler实现类中输出传入的参数值:动态代理的输入参数
2009-3-15 11:29:38 com.itcast.aop.LogHandler invoke
信息: 在这里结束你的事务!java的事务是基于代理的,这下你明白了吗?
2009-3-15 11:29:38 com.itcast.aop.LogHandler invoke
信息: 结束我们的方法...public abstract void com.itcast.aop.IHello.hello(java.lang.String) throws java.lang.Exception
上边的日志说明了我们可以输出的地方,可以做动作的位置
6、总结下
什么是aop,明白了没?解释起来就是“面向切面编程”,动态代理就是一把刀子,在你的程序调用的过程中切来切去。原理就是上边的动态代理。不过spring给我们封装了一下,用cglib这个jar来动态的帮我们生成每个实现类的动态代理,spring的事务控制之类的东西都是基于这个的。总的来说大家不要被穿在java外部的马甲给迷惑住了。事情的原理就是上边那个。
相关文章推荐
- springframework(五)资源国际化
- springframework(十)AOP之Pointcut、Advisor
- java版本的图片的缩放剪辑(二)
- java加解密-密钥长度限制问题
- 用GDB 调试Java程序
- java版本的图片的缩放剪辑(三)
- java6本身支持的MD2和MD5的消息摘要算法
- Java书籍Top 10
- java版本的图片的缩放剪辑(一)
- struts2的教程
- 阿里云安装SVN服务器,eclipse安装svn客户端
- Java NIO类库Selector机制解析(下)
- 工作随笔——Java调用Groovy类的方法、传递参数和获取返回值
- myeclipse9 创建maven工程出错
- springframework(四)Bean的依赖设置与集合对象的处理
- springframework(十三)spring的Dao和JDBC
- Ubuntu下eclipse安装svn插件
- Springframework(一)spring基础概念介绍
- java 内存分配机制
- Java NIO类库Selector机制解析(上)