动态代理技术
来源:互联网 发布:软件开发w模型 编辑:程序博客网 时间:2024/05/12 16:15
1分析代理类的作用与原理及AOP概念
当我们已经开发好了一个类,这时我们需要为这个类添加日志,计数,事务管理 那我们什么做???这时我们可以考虑使用代理。代理模式是对象的结构型模式,代理模式给某一个对象提供了一个代理对象,并由代理对象控制对原对象的引用。
代理分为静态代理和动态代理
1. 代理分类 a) 静态代理:代理类的方法要和接口方式一致! b) 动态代理,JDK动态代理只能对实现了接口的类进行代理,采用JDK动态代理必须实现InvocationHandler接口,采用Proxy类创建相应的代理类。 c) 动态代理的优缺点: d) 面向接口编程方便 e) 使用的是Java反射机制 开销比较大。
2. 分析JVM通过反射生成代理类
JDK 1.5 中代理对象的生成,是通过Proxy 类生成的; 1、创建一个实例对象,先找到有参的构造方法。 2、编写一个最简单的InvotationHander 3、调用动态的方法调用动态的实例对象
代码:三种生成代理对象的方法
packageorg.nagi.proxy;importjava.lang.reflect.Constructor;importjava.lang.reflect.InvocationHandler;importjava.lang.reflect.Method;import java.lang.reflect.Proxy;import java.util.Collection;/** *三种方法生成Collection的代理对象 *@author dell * */publicclass TestProxy { privatestaticCollectionc; publicstaticvoid main(String[] args)throws Exception { TestProxy.CreateProxy1(); TestProxy.CreateProxy2(); TestProxy.getProxy(c); } /** * * 第一种生成代理对象 */ publicstaticvoid CreateProxy1()throws Exception{ //得到代理类 Class classParxy = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class); //得到其构造方法 Constructor con = classParxy.getConstructor(InvocationHandler.class); //实现InvocationHander接口 class MyInvocationHanderimplements InvocationHandler{ public Object invoke(Object proxy, Method method,Object[] args) throws Throwable { returnnull; } } //生成了Collection的一个代理对象 Collection proxy1 = (Collection)con.newInstance(new MyInvocationHander()); } /** * * 第二种生成代理对象 */ publicstaticvoid CreateProxy2()throws Exception{ //得到代理类 Class classParxy = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class); //得到其构造方法 Constructor con = classParxy.getConstructor(InvocationHandler.class); //生成了Collection的一个代理对象 Collection proxy1 = (Collection)con.newInstance(new InvocationHandler(){ @Override public Object invoke(Object proxy, Method method,Object[] args) throws Throwable { returnnull; } }); } /** * * 第三种生成代理对象 */ publicstatic Object getProxy(final Object target) { Object proxy3 = Proxy.newProxyInstance( //得到目标对象的字节码 target.getClass().getClassLoader(), //得到目标对象所实现的接口 target.getClass().getInterfaces(), //实现InvocationHandler接口 new InvocationHandler(){ public Object invoke(Object proxy, Method method,Object[] args) throws Throwable { returnnull; } } ); return proxy3; }}
2.创建动态类及查看其方法列表信息 3.创建动态类的实例对象及调用其方法 4.完成InvocationHandler对象的内部功能
public Object invoke(Object proxy, Method method,Object[] args) throws Throwable { returnnull; }
5.分析InvocationHandler对象的运行原理
我们在调用代理对象的时候,每一次都执行Invocation 里面Invoke方法,而在Invoke 方法需要接收三个数据:哪一个代理对象执行,方法、参数;
5.总结分析动态代理类的设计原理与结构
思考:我们在调用代理对象的时候都要执行InvocationHander 接口里面的Invoke()方法;如果有一千个类都需要生成代理对象并且他们所需添加功能不一样 那我们什么办?
这时候我们就需要重构以一下我们的所生成的代理方法,使它可以适应为任何类添加的心新功能和生成代理对象; 我们就引出AOP 的思想;在为一个类生成代理对象的时候,我们只徐告诉它目标和需要添加的方法,为了提高可复用性和灵活性,我们把需要生成代理的类写进配置文件里面。
6.编写可生成代理和插入通告的通用方法
通知的方法:
importjava.lang.reflect.Method;/** *通知的借口 *即将插入进来的方法 *如:执行的时间 * 记日记 事务管理 *@author dell * */publicinterface Adrice { publicvoid beforeClass(Method method); publicvoid afterClass(Method method);}importjava.lang.reflect.Method;/** *实现通知方法 *@author dell * */publicclass MyAdriceimplements Adrice { @Override publicvoid beforeClass(Method method) { long begain = System.currentTimeMillis(); System.out.println("start....." + begain); } @Override publicvoid afterClass(Method method) { long after = System.currentTimeMillis(); System.out.println("end....." + after); }}/** * 万能代理生成器 * @param target需要代理的对象 * @param adrice需要添加的方法 * @return 代理对象 */ publicstatic Object CreatProxy(final Object target,final Adrice adrice){ Object proxy = Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method,Object[] args) throws Throwable { adrice.beforeClass(method); Object retVal = method.invoke(target, args); adrice.afterClass(method); return retVal; } }); return proxy; }
7.实现类似spring的可配置的AOP框架
首先AOP 存在常用接口:
BeanFactory:负责生产BeanProxyFactoryBean:负责生产Bean 代理对象Adrice: 定义通知的方法接口Config.properties : 配置为哪一个类产生代理对象
代码:
BeanFactory 工厂类packageorg.nagi.Aop;importjava.io.IOException;importjava.io.InputStream;importjava.util.Properties;/** * bean工厂 *@author dell * */publicclass BeanFactory { Properties prop = new Properties(); public BeanFactory(InputStream is ) { try { //从输入流中加载文件 prop.load(is); } catch (IOException e) { e.printStackTrace(); } } //通过name得到Bean public Object getBean(String name)throws Exception{ //从配置文件里面加载类 StringclassName = prop.getProperty(name); //得到文件内存的字节码 Classclazz = Class.forName(className); //生成一个代理对象 Objectbean = clazz.newInstance(); // 如果是代理工厂的对相的话,就加载代理目标类,和通知adrice if(beaninstanceof ProxyFactoryBean){ //如果是代理对象,将其转为ProxyFactoryBean ProxyFactoryBean proxyFactoryBean =(ProxyFactoryBean)bean; //加载目标代理类 Object target = Class.forName(prop.getProperty(name +".target")).newInstance(); //加载目标的通知 AopAdvice advice = (AopAdvice) Class.forName(prop.getProperty(name +".advice")).newInstance(); //设置通知 proxyFactoryBean.setAdvice(advice); //设置代理目标类 proxyFactoryBean.setTarget(target); Object proxy =proxyFactoryBean.CreatProxy(); return proxy; } return bean; }}代理工厂产生类packageorg.nagi.Aop;importjava.lang.reflect.InvocationHandler;importjava.lang.reflect.Method;import java.lang.reflect.Proxy;/** * 代理工厂 * @author dell * */public classProxyFactoryBean { private AopAdvice advice; private Object target; /** * 万能代理生成器 *@param target 需要代理的对象 *@param adrice 需要添加的方法 *@return 代理对象 */ public Object CreatProxy(){ Object proxy = Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy,Method method, Object[] args) throws Throwable { advice.beforeClass(method); Object retVal = method.invoke(target,args); advice.afterClass(method); return retVal; } }); return proxy; } public AopAdvice getAdvice() { return advice; } public void setAdvice(AopAdvice advice) { this.advice = advice; } public Object getTarget() { return target; } public void setTarget(Object target) { this.target = target; }}通知接口类packageorg.nagi.Aop;importjava.lang.reflect.Method;/** *通知的借口 *即将插入进来的方法 *如:执行的时间 * 记日记 事务管理 *@author dell * */publicinterface BaseAdvice { publicvoid beforeClass(Method method); publicvoid afterClass(Method method);}具体通知实现类 package org.nagi.Aop;importjava.lang.reflect.Method;/** *通知的具体实现类 *@author dell * */publicclass AopAdviceimplements BaseAdvice{ @Override publicvoid beforeClass(Method method) { long begain = System.currentTimeMillis(); System.out.println("start....." + begain); } @Override publicvoid afterClass(Method method) { long after = System.currentTimeMillis(); System.out.println("end....." + after); }}
配置文件:config.properties
nagi=org.nagi.Aop.ProxyFactoryBeannagi.advice=org.nagi.Aop.AopAdvicenagi.target=java.util.ArrayList
主函数:
packageorg.nagi.Aop;importjava.io.InputStream;/** *测试类 *@author dell * */publicclass TestAop { publicstaticvoid main(String[] args) { InputStream is = TestAop.class.getResourceAsStream("config.properties"); BeanFactory factory = new BeanFactory(is); try { Object nagi = factory.getBean("nagi"); System.out.println(nagi.getClass().getName()); } catch (Exception e) { e.printStackTrace(); } }}
运行结果生成一个代理对象:com.sun.proxy.$Proxy0
0 0
- 动态代理技术
- 动态代理技术
- 动态代理技术
- 动态代理技术
- java动态代理技术
- cglib动态代理技术
- 动态代理技术
- java技术-静态代理到动态代理
- 代理技术简介(二):JDK动态代理
- 代理技术简介(三):CGlib动态代理
- Spring AOP技术--动态代理
- 动态代理(jdk)+cglib技术
- 初探动态代理反射技术
- Java中的动态代理技术
- 动态代理,工厂模式和反射技术
- 黑马程序员_动态代理技术
- JAVA AOP编程之动态代理技术
- 黑马程序员——动态代理技术
- Timeline中frame mode帧模式中idle占据大片位置
- Dubbo之旅--管理控制台
- 有状态sessionbean 无状态sessionbean
- HDOJ 题目3062 Party(2-sat)
- 求每个元素之和为最大的给定数组的子数组
- 动态代理技术
- javaScript入门 --基础知识
- HDOJ 1157 Who's in the Middle(水)
- OpenGL程序中与glew相关的未处理异常的解决方案
- JS运动基础框架
- 环境反射效果
- 前端#表格冻结
- spring mvc 1
- DES算法