Java动态代理
来源:互联网 发布:软件文件夹命名规则 编辑:程序博客网 时间:2024/04/29 21:33
存在即合理,存在就有存在的理由,java动态代理的存在是为了解决静态代理出现的不足,所以首先看一看什么是静态代理:
有如下接口:
public interface SayHello { void sayHello();}
有如下实现:
public class HelloImpl1 implements SayHello { public void sayHello() { System.out.println("你好"); }}
public class HelloImpl2 implements SayHello { public void sayHello() { System.out.println("Hello"); }}
此时我们如果有一种需求,就是在每一种实现了SayHello接口的sayHello方法前面或后面都加一个固定的操作,比如说每次sayHello前握手,那么我们要去修改每一个实现类吗?如果不使用代理模式,这是必须的,所以出现了静态代理:
我们需要通过代理类取访问具体的实现对象,所以代理类也需要实现具体的接口,这样做是方便我们知道我们在每个方法前后都做了什么,我想,其实代理类不实现SayHello接口也可以使用,但是这样的类多了以后,会很混乱,不知道某个代理类具体是代理什么的,实现接口后,很明显就知道是为了代理某个接口的实现类
public class HelloProxy implements SayHello{ //通过代理取访问这个target目标对象 SayHello target; public HelloProxy(SayHello target) { this.target = target; } public void sayHello() { //先握手 System.out.println("握手"); target.sayHello(); }}
这样代理之后,我们就不用一个个去修改实现类了,只需要将以前调用SayHello实现类的地方改为调用这个HelloProxy代理对象的sayHello()就可以了。如果最开始就使用代理模式,那么为了加“握手”操作就只需要修改代理类,其他地方完全不用修改。
以上就是静态代理,为什么说是静态呢?
试想,如果我们修改了接口呢?如果接口新添加了一个方法,我们是不是要在代理类中也实现这个方法,并且再将“握手”操作添加进去(这样比喻似乎不是很合理,毕竟不是每一种方法前面都需要握手。可以把“握手”换成“安全检查”,有一种情况,是我们在调用这个类的方法前都需要进行安全检查,那这种说法就是合理的)。
所以,动态代理就是这样的:当接口改变时,我们不需要改变代理类,不需要手动的在每个新方法前面都加上“握手”操作。
动态代理如何实现呢?Java给我们提供了简单方法,分两步:
(1)说明我们想要在每个方法前后加上什么操作(不限定接口)
(2)JVM运行时动态的生成代理类(限定接口,只能生成代理某个接口的代理类,在这种接口每个方法前后都加上第(1)步中规定的操作)
我们来实现SayHello接口的代理,在方法前面加上“握手”操作,按照上面的步骤来进行:
(1)说明我们想要在每个方法前后加上什么操作
//我们需要实现InvocationHandler接口,告诉我们需要添加“握手”操作public class Operation implements InvocationHandler { //代理的对象是这个 Object originObj; public Operation(Object originObj) { this.originObj = originObj; } //这里使用反射来实现调用类内部的方法,所以参数有:类实例,方法,给方法的参数。 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("握手"); return method.invoke(originObj, args); }}
这里没有指定接口,所以任意一个类都可以使用这个代理,来实现在前面加上“握手”操作。
(2)JVM运行时动态的生成代理类
我们来生成一个SayHello接口的代理类
SayHelloImp hello = new SayHelloImp();//生成一个操作对象,告诉JVM要添加什么操作Operation operation = new Operation(hello);//后面的3个参数,后两个告诉Proxy要代理什么接口,添加什么操作。第一个暂时不清楚。SayHello helloProxy = (SayHello) Proxy.newProxyInstance(hello.getClass().getClassLoader(),hello.getClass().getInterfaces(),operation);
好了,这就是动态代理的概念以及使用,想知道最终生成的代理实例代码是什么样子,请移步我的另一片博文
- Java 代理,动态代理
- [Java] Java 动态代理
- java代理及动态代理
- java代理模式--动态代理
- Java静态代理、动态代理
- Java 代理之 动态代理
- Java 代理与动态代理
- java静态代理,动态代理
- 代理模式&java动态代理
- Java代理与动态代理
- Java静态代理动态代理
- JAVA代理模式--动态代理
- java 代理和动态代理
- JAVA动态代理 代理模式
- Java动态代理--jdk代理
- Java动态代理--cglib代理
- Java 代理与动态代理
- java代理模式-动态代理
- 第三周项目2:本月有几天?
- 校内欢乐赛之爆零季 T2
- App推送功能-APNS
- 第32讲项目4——输出小星星
- 创建cocos2d-x工程及文件夹解析
- Java动态代理
- URL中“#”的作用
- [Java语言] Spring+Mybatis+Velocity配置
- Java中 == 和equals的区别
- Android毛玻璃效果的实现(本文系转载一种快速毛玻璃虚化效果实现)
- Pascal's Travels
- ActiveMQ发消息、收消息、持久化,查询队列剩余消息数、出队数的实现
- 代码健壮性--异常处理中try catch finall throw throws五个关键字学习
- Ubuntu安装