Java动态代理-JDK自带实现
上篇文章讲解了什么是静态代理,但是静态代理有一个问题就是需要建立很多的代理类,这样我们需要修改代理的方法的时候,需要在每个类中都要修改,这对于我们来说:当代理类很多的时候工作量就会成倍的增加。
于是针对上述问题,人们就提出了解决方案,我们在运行中来实现代理类的创建,也就是今天要讲解的主题——动态代理,首先先说的是JDK自带的动态代理的实现。
JDK自带的代理实现中最重要的两个内容:一是Proxy类,另一个是InvocationHandler接口。这两个是实现动态代理必须要用到的类和接口。
1)对于InvocationHandler接口,API给出了这样的定义:
InvocationHandler 是代理实例的调用处理程序 实现的接口。
每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,
将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法
Object invoke(Object proxy,
Method method,
Object[] args)
throws Throwable
proxy:指代理的那个真实对象
method:指调用真是对象的某个方法Method对象
args:指调用真实对象某个方法时接受的参数
2)Proxy类:
提供用于创建动态代理类和实例的静态方法,它还是由newProxyInstance方法创建的所有动态代理类的超类。
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
loader:定义代理类的类加载器
interface:代理类要实现的接口列表
h:指派方法调用处理程序
返回值:一个带有代理类的指定调用处理程序的代理实例,它由指定的类加载器定义,并实现指定的接口
也就是(返回一个由类加载器指定的代理类,它具有代理类Proxy中方法)这是我个人的理解
以上已经对于JDK中用到的内容进行了简单的了解,接下来我们来看如何在代码中实现动态代理,
1、定义一个接口
public interface Hello {
void say(String name);
}
2、定义一个类来实现这个接口,这个类就是我们的真实对象,HelloImpl
public class HelloImpl implements Hello {
@Override
public void say(String name) {
System.out.println("Hello!"+name);
}
}
3、定义一个动态代理,每个动态代理类都必须实现InvocationHandler这个接口
public class DynamicProxy implements InvocationHandler {
private Object target;
public DynamicProxy(Object target){
this.target=target;
}
@SuppressWarnings("unchecked")
public <T> T getProxy(){
return (T) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this
);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object result =method.invoke(target,args);
after();
return result;
}
private void before(){
System.out.println("Before");
}
private void after(){
System.out.println("After");
}
}
4、接下来就是在客户端调用
public class Test {
public static void main(String[] args){
Hello hello =new HelloImpl();
DynamicProxy dynamicProxy = new DynamicProxy(hello);
Hello helloProxy=(Hello) Proxy.newProxyInstance(
hello.getClass().getClassLoader(),
hello.getClass().getInterfaces(),
dynamicProxy
);
helloProxy.say("Jack");
}
}
问题:由于上述在客户端调用过程中,每次动态创建代理类都会使用newProxyInstance这个方法,我们对其进行一层封装,如下:
1、封装一个类,HelloProxy
public class HelloProxy implements Hello {
private Hello hello;
public HelloProxy(){
hello=new HelloImpl();
}
@Override
public void say(String name) {
before();
hello.say(name);
after();
}
private void before(){
System.out.println("Before");
}
private void after(){
System.out.println("After");
}
}
2、客户端调用
public class Test {
public static void main(String[] args){
DynamicProxy dynamicProxy=new DynamicProxy(new HelloImpl());
Hello helloProxy =dynamicProxy.getProxy();
helloProxy.say("Jack");
}
}
Java动态代理-JDK自带实现的更多相关文章
- java 动态代理示例,带主要注释
Java proxy是基于反射,仅仅支持基于接口的动态代理. java 动态代理是一切架构的基础,必须了解. 废话少说,先上代码获得感性认识. 示例代码有主要注释. 接口: public interf ...
- Java动态代理 ----- jdk代理与cglib代理
1.jdk代理 针对接口进行代理,接口可以没有方法, InvocationHandler会拦截所有方法,不过好像意义不大....只能执行Object类的方法,执行结果有点奇怪... package t ...
- [转]java动态代理(JDK和cglib)
转自:http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html java动态代理(JDK和cglib) JAVA的动态代理 代理模式 代理 ...
- java动态代理(JDK和cglib)
转:http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html JAVA的动态代理 代理模式 代理模式是常用的java设计模式,他的特征是代 ...
- 《转》JAVA动态代理(JDK和CGLIB)
该文章转自:http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html JAVA的动态代理 代理模式 代理模式是常用的java设计模式,他的 ...
- 《转》java动态代理(JDK和cglib)
该文章转自:http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html JAVA的动态代理 代理模式 代理模式是常用的java设计模式,他的 ...
- java动态代理(JDK和cglib实现对比)
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt214 JAVA的动态代理 代理模式 代理模式是常用的java设计模式,他的特 ...
- Spring学习(四)—— java动态代理(JDK和cglib)
JAVA的动态代理 代理模式 代理模式是常用的java设计模式,他 的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托 ...
- java 静态代理 JDK动态代理 Cglib动态代理
下面以一个简单的银行账户为例讲述讲述动态代理. 设计一个银行账户类,包含用户的账户余额,实现查询和更新余额功能 这个系统用了一段时间,有客户要求对账说账户余额给弄错了?因为上面没有存取款记录,最后银行 ...
随机推荐
- 一文带你了解elasticsearch
一文带你了解elasticsearch cxf2102100人评论160人阅读2019-07-02 21:31:36 elasticsearch es基本概念 es术语介绍 文档Document ...
- spring boot Websocket
本文只作为个人笔记,大部分代码是引用其他人的文章的. 参考: https://blog.csdn.net/moshowgame/article/details/80275084 在springboot ...
- 移相器——K波段有源移相器设计
博主之前在做一款K波段有源移相器,所用工艺为smic55nmll工艺,完成了几个主要模块的仿真,现对之前的工作做个总结. K波段的频率范围是18G——27GHz,所设计移相器的工作频率范围是19G—— ...
- Web负载均衡学习笔记之K8S内Ngnix微服务服务超时问题
0x00 概述 本文是从K8S内微服务的角度讨论Nginx超时的问题 0x01 问题 在K8S内部署微服务后,发现部分微服务链接超时,Connection Time Out. 最近碰到了一个 Ngin ...
- webbrowser实现一个进程一个代理的办法
public static void RefreshIESettings(string strProxy) { const int INTERNET_OPTION_PROXY = 38; const ...
- CentOS 7 新系统 手动配置网络 简要步骤
一.配置网卡文件 1.修改网卡文件进入网卡配置文件目录 cd /etc/sysconfig/network-scripts 2.查看网卡文件 # ls CentOS中网卡文件一般为 ifcfg-ens ...
- Django(一)初始
一:Web开发中的基本术语 1.两种架构 (1)cs架构 Client/Server:客户端-服务端架构 优点:CS能充分发挥客户端PC的处理能力,很多工作可以在客户端处理后在提交给服务器,用户体验好 ...
- Mybatis事物浅谈
本篇文章主要对Mybatis事物进行基础的介绍.先回顾JDBC事物,再了解Mybatis里面的事物应用. 1.JDBC的事务管理回顾 JDBC的事务管理是基于Connection对象实现的: 开启事务 ...
- FineReport连接SSAS多维数据库
1.服务器——定义数据连接,如下图: 2.配置SSAS服务器地址及登录名密码: 注意这里的用户名.密码是指的服务器的登录名和登录密码,也就是你远程桌面的登录用户名和密码,不是数据库的登录用户名密码. ...
- Django:RestFramework之-------版本控制
6.版本控制 从URL通过get传参获取版本. 6.1自定义版本控制 from rest_framework.views import APIView class ParamVersion(objec ...