java动态代理实现
来源:互联网 发布:9377皇图翅膀进阶数据 编辑:程序博客网 时间:2024/06/11 08:57
Spring AOP的源码中用到了两种动态代理来实现拦截切入功能:jdk动态代理和cglib动态代理。两种方法同时存在,各有优劣。jdk动态代理是由内部java的反射机制来实现的,cglib动态代理底层则是借助asm来实现的。总的来说,反射机制在生成类的过程中比较高效,而asm在生成类之后的相关执行过程中比较高效(可以通过将asm生成的类进行缓存,这样解决asm生成类过程低效问题)。还有一点必须注意:jdk动态代理的应用前提,必须是目标类基于统一的接口。如果没有上述前提,jdk动态代理不能应用。由此可以看出,jdk动态代理有一定的局限性,cglib这种第三方类库实现的动态代理应用更加广泛,且在效率上更有优势。
cglib做动态代理时不要求被代理类实现统一接口。
来看一个我自己编写的jdk和cglib例子:
加入
代理类:
import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import org.springframework.beans.factory.FactoryBean;import org.springframework.cglib.proxy.Enhancer;import org.springframework.cglib.proxy.MethodInterceptor;import org.springframework.cglib.proxy.MethodProxy;import dynamicProxy.service.IHandler;/** * Created by liukang Date: 2017/1/23 Time: 12:07 jdk 动态代理测试类T */public class MyInvocationHandlerTest <ProxyClass> implements FactoryBean<ProxyClass> { private ProxyClass iHandler; /** * 代理类 */ private ProxyClass proxyIHandler; private _ProxyTypeEnum proxyTypeEnum; public MyInvocationHandlerTest(ProxyClass iHandler,_ProxyTypeEnum proxyTypeEnum){ this.iHandler = iHandler; this.proxyTypeEnum = proxyTypeEnum; } public ProxyClass getObject() throws Exception { if(this.proxyTypeEnum.equals(_ProxyTypeEnum.JDK)){ if (proxyIHandler == null) { _InvocationHandler myInvocationHandler = new _InvocationHandler(); proxyIHandler = (ProxyClass) Proxy.newProxyInstance(this.iHandler.getClass().getClassLoader(), this.iHandler.getClass().getInterfaces(), myInvocationHandler); } } if(this.proxyTypeEnum.equals(_ProxyTypeEnum.CGLIB)){ Enhancer e = new Enhancer(); e.setSuperclass(iHandler.getClass()); e.setCallback(new _CglibProxy()); proxyIHandler = (ProxyClass) e.create(); } return proxyIHandler; } public Class<?> getObjectType() { return IHandler.class; } public boolean isSingleton() { return true; } public enum _ProxyTypeEnum{ JDK,CGLIB; } /** * jdk代理类实现 */ public class _InvocationHandler implements InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object proxyObject = null; if ("handle".equals(method.getName())) { System.out.println("before handle!"); proxyObject = method.invoke(MyInvocationHandlerTest.this.iHandler, args); System.out.println("end handle!"); } else { proxyObject = method.invoke(MyInvocationHandlerTest.this.iHandler, args); } return proxyObject; } } /** * cglib代理类实现 cglib的好处是 代理的类不用都实现同一个接口 */ public class _CglibProxy implements MethodInterceptor{ public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("++++++before " + methodProxy.getSuperName() + "++++++"); System.out.println(method.getName()); Object o1 = methodProxy.invokeSuper(o, objects); System.out.println("++++++end " + methodProxy.getSuperName() + "++++++"); return o1; } }}
service层:
/** * Created by liukang * Date: 2017/1/23 * Time: 12:15 * 处理器接口 */public interface IHandler { void handle(Object...objects);}
package dynamicProxy.service.impl;import dynamicProxy.model.UserEntity;import dynamicProxy.service.IHandler;/** * Created by liukang Date: 2017/1/23 Time: 12:28 姓名处理类 */public class NameHandler implements IHandler { public void handle(Object... objects) { System.out.println("nameHandler start!"); if (objects == null || objects.length < 1) { System.out.println("nameHandler objects is null"); return; } UserEntity user = (UserEntity) objects[0]; user.setName(user.getName()+" Handle"); System.out.println("nameHandler done!"); }}model层:
package dynamicProxy.model;/** * Created by liukang * Date: 2017/1/23 * Time: 12:48 */public class UserEntity { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public UserEntity(String name,int age){ this.name = name; this.age = age; }}
测试类:
import dynamicProxy.model.UserEntity;import dynamicProxy.service.IHandler;import dynamicProxy.service.impl.NameHandler;/** * Created by liukang * Date: 2017/1/23 * Time: 12:34 */public class TestProxy { public static void main(String args[]){ //jdk MyInvocationHandlerTest<IHandler> myInvocationHandlerTest = new MyInvocationHandlerTest(new NameHandler(), MyInvocationHandlerTest._ProxyTypeEnum.JDK); UserEntity user = new UserEntity("name",16); try { IHandler nameHandler = myInvocationHandlerTest.getObject(); nameHandler.handle(user); } catch (Exception e) { e.printStackTrace(); } System.out.println(user.getName()); //cglib MyInvocationHandlerTest<IHandler> myInvocationHandlerTest2 = new MyInvocationHandlerTest(new NameHandler(), MyInvocationHandlerTest._ProxyTypeEnum.CGLIB); UserEntity user2 = new UserEntity("name2",18); try { IHandler nameHandler2 = myInvocationHandlerTest2.getObject(); nameHandler2.handle(user2); } catch (Exception e) { e.printStackTrace(); } System.out.println(user2.getName()); }}
0 0
- Java动态代理实现
- Java动态代理实现
- JAVA动态代理实现
- Java 动态代理实现
- Java动态代理实现
- Java动态代理实现
- Java动态代理实现
- Java动态代理实现
- Java动态代理实现
- Java动态代理实现
- Java动态代理实现
- Java动态代理实现
- 动态代理--java实现
- java动态代理实现
- Java动态代理实现
- JAVA动态代理实现
- java 动态代理实现
- java 实现动态代理
- 专业游戏玩家如何选导热硅脂
- UIVIEW的各个属性详解
- JS识别不同浏览器信息
- Java 枚举(enum) 详解7种常见的用法
- Robot Framework自动化测试(一)---第一个脚本
- java动态代理实现
- LTE TS36.523-1 7.1.1.1
- java配置session监听器
- Java锁的种类以及辨析
- pch有以下几个作用
- # 对 Android 应用被强杀重回应用的优化处理(重走应用流程)
- Linux下实现C语言的http请求实现
- 内存管理和垃圾回收
- strtod将字符串转换成浮点数