Java 基础【19】代理
2019-03-01 10:14:49来源:博客园 阅读 ()
Java 代理(Proxy)模式与现实中的代理含义一致,如旅游代理、明星的经纪人。
在目标对象实现基础上,增加额外的功能操作,由此来扩展目标对象的功能。
JavaWeb 中最常见的过滤器、Struts 中的拦截器、Spring 中的 AOP...都有代理的应用。
此篇博客将编写例子描述 Java 底层技术和开源类库Cglib实现代理的方法,并对比各方法的优缺性。
1.JDK 静态代理
抽象接口:
/** * 用户服务抽象 */ public interface UserService { /** * 用户登录 * * @param userName 用户名 * @param pwd 密码 * @return 登陆结果 */ String login(String userName, String pwd); }
实现该接口:
/** * 用户服务实现 * * @author Rambo 2019-03-01 **/ public class UserServiceImpl implements UserService { @Override public String login(String userName, String pwd) { Console.log("进行登陆逻辑........."); return "登陆结果"; } }
编码代理类,实现该接口,代理目标作为私有对象:
/** * 用户服务代理类 * * @author Rambo 2019-03-01 **/ public class UserServiceProxy implements UserService { private UserService userService; UserServiceProxy(UserService userService) { this.userService = userService; } @Override public String login(String userName, String pwd) { Console.log("登陆前扩展....."); userService.login(userName, pwd); Console.log("登陆后扩展....."); return "登陆结果"; } }
编写测试类:
@Test public void testLogin() throws Exception { UserServiceProxy userServiceProxy = new UserServiceProxy(new UserServiceImpl()); userServiceProxy.login("rambo","111111"); }
这应该是最原始实现代理的样子,缺点也很明显,需要编码代理类,势必导致代理类冗余,且当目标类增加或删除方法时,需要维护代理类。
2.JDK 动态代理(接口代理)
代理核心方法 Proxy.newProxyInstance :
/** * JDK 生成代理类 * @param loader 当前目标对象使用类加载器 * @param interfaces 目标对象实现的接口的类型 * @param h 事件处理对象,通过反射执行目标对象的方法 * @return 生成的代理类实例 */ @CallerSensitive public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces, InvocationHandler h)
代理工厂类:
/** * 代理工厂类 * * @author Rambo 2019-03-01 **/ public class JdkProxyFactory { private Object target; public JdkProxyFactory(Object target) { this.target = target; } public Object getProxyInstance() { return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Console.log("执行目标前的扩展......"); Object returnValue = method.invoke(target, args); Console.log("执行目标后的扩展......"); return returnValue; } }); } }
编写测试类:
@Test public void testGetProxyInstance() throws Exception { UserService proxyInstance = (UserService) new ProxyFactory(new UserServiceImpl()).getProxyInstance(); proxyInstance.login("rambo", "111111"); }
目标对象需要实现接口,代理对象是可以不用实现接口的。
使用目标对象接口、自定义调用处理类 InvocationHandler 实例化代理类,内部通过反射调用目标对象的方法。
3.Cglib 代理 (子类代理)
当目标对象是个单独的类,没有实现任何接口,是无法使用上述两种代理方法,这时候怎么办?
可以使用 Cglib 代理(需要单独引入 cglib 类库),自定义目标类的子类进行目标对象的扩展,且这种扩展进行在 Jvm 运行期。
Cglib 底层是通过一个小而快的字节码处理框架 Asm 来转换字节码并生成新的类。
不局限目标类存在方式、运行期增强目标类、底层精致的 asm 字节码框架,使 Cglib 成为许多 AOP 框架生成动态代理的首选。
代理工厂类:
/** * Cglib 动态代理工厂 * * @author Rambo 2019-03-01 **/ public class CgbProxyFactory implements MethodInterceptor { private Object target; public CgbProxyFactory(Object target) { this.target = target; } public Object getProxyInstance() { Enhancer en = new Enhancer(); en.setSuperclass(target.getClass()); en.setCallback(this); return en.create(); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { Console.log("执行目标前的扩展......"); Object returnValue = method.invoke(target, args); Console.log("执行目标后的扩展......"); return returnValue; } }
编写测试用例:
@Test public void testGetProxyInstance() throws Exception { UserService proxyInstance = (UserService) new CgbProxyFactory(new UserServiceImpl()).getProxyInstance(); proxyInstance.login("rambo","111111"); }
JDK InvocationHandler 、Cglib MethodInterceptor 具体实现的细节,如你有兴趣可翻翻源码,这里就不赘述了。
至此代理的几种方式已经使用都已描述完毕,如有不符,还望斧正。
原文链接:https://www.cnblogs.com/java-class/p/10455094.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
下一篇:10个经典的Java面试题集合
- 国外程序员整理的Java资源大全(全部是干货) 2020-06-12
- 2020年深圳中国平安各部门Java中级面试真题合集(附答案) 2020-06-11
- 2020年java就业前景 2020-06-11
- 04.Java基础语法 2020-06-11
- 代理项 Surrogate 2020-06-11
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash