玩转JDK动态代理
来源:互联网 发布:程序员修炼之道txt 编辑:程序博客网 时间:2024/05/21 17:10
概述
JDK动态代理的两个主要类:
java.lang.reflect.InvocationHandler:执行代理对象的方法时的回调接口。在这个接口中编写与代理业务相关的代码。它在JDK中的定义如下。
public interface InvocationHandler { /** * @param proxy JDK生成的代理对象 * @param method 被代理接口的方法对象 * @param args 方法执行的参数 * @return */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;}
java.lang.reflect.Proxy:调用它的静态方法newProxyInstance创建代理对象。它为代理的接口创建实现类,并为其创建一个以InvocationHandler对象为参数的构造方法,每个代理方法都会执行InvocationHandler对象的invoke方法。
运用
A. 鱼儿开始和停止游泳时告诉大家
通过jdk动态代理,可以在一个行为前后添加性能监控、日志等操作。
下面我们来记录鱼儿开始和停止游泳的日志。
(1)定义一个FishService接口和实现
public interface FishService{ /** * 游泳 **/ void swimming();}
实现如下
public class FishServiceImpl implements FishService { public void swimming() { System.out.println("游泳中...."); }}
(2)定义SimpleInvocationHandler 用于获得代理对象和和方法回调。
在这里该类的定义稍微复杂了点,直接看我的注释就是。
public class SimpleInvocationHandler implements InvocationHandler { private Set<Class> interfaces = new HashSet<>(); // 接口和默认实现 private Map<Class, Object> additionalItf = new HashMap<>(); /** * 添加被代理接口和其实现 * @param itf 被代理的接口 * @param defaultImpl 接口的默认实现 * @param <T> */ public <T> void additionalItf(Class<T> itf, T defaultImpl) { additionalItf.put(itf, defaultImpl); interfaces.add(itf); } /** * 获得代理对象 * 通过Proxy的静态方法newProxyInstance创建代理 * @return 返回代理对象 */ public Object getProxy() { ClassLoader loader = SimpleInvocationHandler.class.getClassLoader(); Class[] interfaces = this.interfaces.toArray(new Class[0]); return Proxy.newProxyInstance(loader, interfaces, this); } /** * 实现InvocationHandler接口的invoke方法。 * 该方法在执行代理对象的方法时,会回调执行。 * @return 返回被代理的方法的返回值 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String name = method.getName(); try { System.out.println(name + "方法执行前"); // 根据方法的声明类对象,获取方法的调用者 Object defaultImpl = additionalItf.get(method.getDeclaringClass()); if (defaultImpl == null) { System.out.println(name + "方法无默认实现"); return null; } return method.invoke(defaultImpl, args); } finally { System.out.println(name + "方法执行后"); } }}
(3)创建代理,并执行接口方法。
public class MainObject { public static void main(String[] args) throws Exception { SimpleInvocationHandler handler = new SimpleInvocationHandler(); // 添加被代理接口和实现类 handler.additionalItf(FishService.class, new FishServiceImpl()); // 获得代理对象 FishService fishService = (FishService) handler.getProxy(); // 通过代理对象执行代理方法 fishService.swimming(); }}
输入如下。
swimming方法执行前游泳中....swimming方法执行后
B. 让鱼儿飞起来
可以通过JDK动态代理多个接口,使对象提供更多的服务。操作如下。
(1)定义一个飞行的接口和一个默认实现。
interface FlyService { /** * 飞行 */ void fly();}
实现飞行接口,如下。
public class FlyServiceImpl implements FlyService { @Override public void fly() { System.out.println("飞..."); }}
(2)通过SimpleInvocationHandler 创建一个会飞的鱼,代码如下。
class MainObject { public static void main(String[] args) throws Exception { SimpleInvocationHandler handler = new SimpleInvocationHandler(); handler.additionalItf(FishService.class, new FishServiceImpl()); handler.additionalItf(FlyService.class, new FlyServiceImpl()); FishService fishService = (FishService) handler.getProxy(); fishService.swimming(); // 让鱼飞起来 ((FlyService)fishService).fly(); }}
运行结果:
swimming方法执行前游泳中....swimming方法执行后fly方法执行前飞...fly方法执行后
总结
JDK动态代理的作用:
(1)通过JDK代理可以为接口创建代理。
(2)通过JDK代理可以为类增加更多的行为。
JDK动态代理的不足:
只能为接口创建代理,而不能为一个class类创建代理。
0 0
- 玩转JDK动态代理
- 代理模式,JDK动态代理
- Java动态代理--jdk代理
- 代理模式-JDK动态代理
- JDK动态代理实现简单AOP--转
- JDK动态代理本质(转)
- JDK中的动态代理
- JDK动态代理
- JDK动态代理
- JDK动态代理
- jdk动态代理(暂)
- JDK动态代理
- JDK动态代理实例
- jdk 动态代理
- JDK动态代理
- JDK动态代理说明
- jdk动态代理
- JDKDynamicProxy JDK动态代理
- 1037. Magic Coupon (25)
- getParameter
- 关于我及新年计划
- PAT BASIC 1023 组个最小数
- 硬盘分区
- 玩转JDK动态代理
- 496. Next Greater Element I
- tp控制器------(六)
- java直接调用php文件,和php接收参数
- getAttribute()与getParameter的区别
- 一张图搞定android学习路径
- RadioGrop嵌套Radiobutton 切换不同的 fragment
- 基于代理类ProxyFactoryBean的AOP实现---异常通知编码实例
- 【JAVA学习】——J2EE规范