关于java 动态代理详细讲解
来源:互联网 发布:怎么卖域名 编辑:程序博客网 时间:2024/05/29 14:10
近来比较闲,又看来下java代理的api 感觉之前对他的理解不是很深 现在又重新看了一遍 记录下自己的感受吧!
那么我们认识下 什么是代理呢? 小弟语文学的不好 ,就用如下代码来说吧!
我们模仿 登录 注册 业务案列 来讲解
/*** 定义登录接口**/interface login{ boolean login(String username,String password); boolean creadUser(String username,String password);}/*** 实现登录接口**/class loginImpl implements login {@Overridepublic boolean login(String username, String password) {System.out.println("出来核心登录逻辑"+ "帐号是 : "+username +" 密码是: "+ password);return true;}@Overridepublic boolean creadUser(String username, String password) {System.out.println("我只是注册 不需要家其他业务处理" +" 注册的帐号: "+username +" 注册时的密码 : "+password);return true;}} /** * * 登录成功也需要添加业务逻辑 * @author jade * */class Pox extends loginImpl{@Overridepublic boolean login(String username, String password) { System.out.println("登录前业务添加逻辑 pox 1 静态代理"); boolean is= super.login(username, password); System.out.println("登录后业务添加逻辑 pox 1 静态代理");return is;}} /** ----------------------------- 讲解代理 开始 end ***/
如上 Pox 的存在原因是因为需求的变动,又不想去改动原来的业务 所以他就出现了! Pox 就是传说中的代理
上面代理的缺点显易见 - 一个代理只能为一个接口服务 为了解决这个问题 java 就出来了动态代理
那就何为动态代理 ? 说白了就是 一个接口《java.lang.reflect.invocationHandler》 一个类《java.lang.reflect 类 Proxy》 如何不是和了解的 话几分钟看下api 好那我们把上面的静态代理修改成jdk 动态代理
class Pox2 implements InvocationHandler{private Pox p;Pox2(){}; Pox2(Object o){this.p=o;}////Object getPox(Object o){////this.p = o; // //取得代理对象 // return Proxy.newProxyInstance(o.getClass().getClassLoader(), // o.getClass().getInterfaces(), this); // 得到代理对象有很多方式 可以参阅 api 我这里写了两种一个是通过构造函数得到 一个是通过调用getPox :查了网上论坛大部分用//的是getPox ////}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable { Object r=null; // 如下演示 业务处理 if(method.getName().equals("login")){ System.out.println("登录前业务添加逻辑 pox 2 动态代理"); r= method.invoke(p, args); System.out.println("登录后业务添加逻辑 pox 2 动态代理"); }else{ r= method.invoke(p, args); }return r;}}
public class StadyPox {public static void main(String[] args) { InvocationHandler proxy2 = new Pox2(new loginImpl()); login login3=(login) Proxy.newProxyInstance(loginImpl.class.getClassLoader(),loginImpl.class.getInterfaces() , proxy2); login3.login("c", "d"); login3.creadUser("e", "f");
</pre><pre name="code" class="java">//---------------------- 如上是通过构造函数 实现的 如下是直接通过getPox()得到
<pre name="code" class="java" style="color: rgb(146, 147, 175); font-size: 11px;">// login login2 = (login) proxy2.getPox(new loginImpl()); // login2.login("a", "b");
// <span style="font-family: Times;">login2</span><span style="font-family: Times;">.creadUser("e", "f");</span>}}
关于动态代理的讲解就到这里了 看下
Proxy.newProxyInstance(loginImpl.class.getClassLoader(),loginImpl.class.getInterfaces() , proxy2) 你看到了什么呢? loginImpl.class.getInterfaces() ?? 这个的意思就是 他必须有实现接口 那就是jdk 动态代理 必须要有接口 才能使用
那如果在没有接口的情况下 那我们如何实现动态代理 ?? cglib 代理
cglib 代理 其原理是 继承实现类 在继承的原则下面覆盖父类方法体 也就是 final 类不能代理 因为 他不能被继承
再次模拟 登录业务 讲解 cglib
class loginImpl2 {public boolean login(String username, String password) {System.out.println("出来核心登录逻辑"+ "帐号是 : "+username +" 密码是: "+ password);return true;}public boolean creadUser(String username, String password) {System.out.println("我只是注册 不需要家其他业务处理" +" 注册的帐号: "+username +" 注册时的密码 : "+password);return true;}}
由上面代码可以看出 , 没有实现接口 。如下写cglib 代理类 写法方式和jdk 代理类似
class cglib implements MethodInterceptor{ private Object pox; public Object getPox(Object o) { pox = o; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.pox.getClass()); // 回调方法 enhancer.setCallback(this); // 创建代理对象 return enhancer.create(); } @Override // 回调方法 public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("事物开始"); proxy.invokeSuper(obj, args); System.out.println("事物结束"); return null; } }以上就是cglib动态代理 来个测试下吧!
class TestCglib {public static void main(String[] args) {loginImpl2 login4 = new loginImpl2();cglib cglibProxy = new cglib();loginImpl2 hw = (loginImpl2) cglibProxy.getInstance(login4);System.out.println(hw.getClass().getSuperclass());System.out.println("ssksksk " + login4.getClass().getSuperclass());hw.login("aa", "bb");}}
得出的结果:
class jada.java.lang.reflect.loginImpl2
ssksksk class java.lang.Object
事物开始
出来核心登录逻辑帐号是 : aa 密码是: bb
事物结束
class jada.java.lang.reflect.loginImpl2 有此可以得出 --他说继承了 loginImpl2
开始出来个疑问 直接打印代理类
System.out.println(hw) 结果是null 并且它执行了一次 <span style="color: rgb(146, 147, 175);font-size:18px;"></span><pre name="code" class="java"> public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable
同样的方式 我打印了 jdk动态实现的
public class StadyPox {public static void main(String[] args) {loginImpl a = new loginImpl();InvocationHandler proxy2 = new Pox2(a);login login3 = (login) Proxy.newProxyInstance(loginImpl.class.getClassLoader(),loginImpl.class.getInterfaces(), proxy2);System.out.println(a);System.out.println(login3);login3.login("c", "d");// login login2 = (login) new Pox2().bingTage(new loginImpl());// login2.login("a", "b");}}出来的结果是:
jada.java.lang.reflect.loginImpl@2e8f4fb3
jada.java.lang.reflect.loginImpl@2e8f4fb3
登录前业务添加逻辑 pox 2 动态代理
出来核心登录逻辑帐号是 : c 密码是: d
登录后业务添加逻辑 pox 2 动态代理
- 关于java 动态代理详细讲解
- java代理详细讲解
- java动态代理jdk与cglib详细讲解
- java中的代理和动态代理讲解
- 关于Java动态代理
- java--关于动态代理
- Java 动态代理机制分析及扩展_讲解比较详细,收藏
- jdk动态代理最详细讲解---学习笔记
- 代理模式详细讲解
- 关于java的动态代理
- 关于java基础--动态代理
- 关于java的动态代理
- 关于java动态代理模式
- 关于java中的动态代理
- 最详细的代理讲解--JDK动态代理和cglib代理
- 动态代理简单讲解
- 最详细的代理讲解--JDK动态代理和cglib代理 (类比spring中事物的代理)
- 黑马程序员--java高新技术--动态代理技术的深入讲解
- 数据结构之线性表2顺序表
- Java中ArrayList与Vector集合的区别
- Vuforia SDK---- Vuforia可以追踪多少Target
- 【遇见Android bug】Android library project cannot be launched
- 51置业网提醒二套房认定注意事项
- 关于java 动态代理详细讲解
- JavaScript精炼---类(class)、构造函数(constructor)、原型(prototype)
- T_SQL 将一列多行数据合并为一行
- Lucene 学习 1 Hello World
- PL/SQL DEVELOPER 设置大小写
- android parcel
- TestNG+Selenium Webdriver 数据(Excel)驱动的方法
- hdu 5014 Number Sequence 西安网络赛
- 一个星期的提前2小时早起试验给我带来的变化