Java的动态代理(DynamicProxy)
代理的概述
代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。
代理模式UML图:

为了保持行为的一致性,代理类和委托类通常会实现相同的接口,所以在访问者看来两者没有丝毫的区别。通过代理类这中间一层,能有效控制对委托类对象的直接访问,也可以很好地隐藏和保护委托类对象,同时也为实施不同控制策略预留了空间,从而在设计上获得了更大的灵活性。Java 动态代理机制以巧妙的方式近乎完美地实践了代理模式的设计理念。
动态代理的使用场景
动态代理的好处是它比较灵活,可以在运行的时候才切入改变类的方法,而不需要预先定义它。
动态代理一般我们比较少去手写,但我们用得其实非常多。
在Spring项目中用的注解,例如依赖注入的@Bean、@Autowired,事务注解@Transactional等都有用到,
换言之就是Srping的AOP(切面编程)。
这种场景的使用是动态代理最佳的落地点,可以非常灵活地在某个类,某个方法,某个代码点上切入我们想要的内容,就是动态代理其中的内容。
静态代理
代理类和被代理类 实现同一个接口
缺点就是一个代理类只能针对一个接口
package Proxy.staticProxy; /**
* 创建Person接口
*/
public interface Person {
// 交钱的方法
void giveMoney();
}
package Proxy.staticProxy; /**
* 需要代理的对象:
*
* 学生类
*/
public class Student implements Person {
private String name; public Student(String name) {
this.name = name;
} @Override
public void giveMoney() { System.out.println(name + "交保护费50");
}
}
package Proxy.staticProxy; /**
* 学生代理类,也实现了Person接口,保存一个学生实体,这样既可以代理学生产生行为
*/
public class StudentsProxy implements Person { //被代理的学生
Student stu; public StudentsProxy(Person stu) {
//只代理学生对象
if (stu.getClass() == Student.class) {
this.stu = (Student) stu;
}
} //代理上交保护费,调用被代理学生的交保护费行为
@Override
public void giveMoney() {
stu.giveMoney();
}
}
 package Proxy.staticProxy;
 public class StaticProxyTest {
     public static void main(String[] args) {
         Person zhangsan = new Student("张三");
         Person moneitor = new StudentsProxy(zhangsan);
         moneitor.giveMoney();
         /**
          * 运行结果:
          *
          * 张三交保护费50
          */
     }
 }
动态代理
动态代理分为两种 jdk 和 cglib
jdk
jdk 代理主要用到了
接口InvocationHandler 此接口只有一个方法(代码如下)
InvocationHandler的实现类可以理解成具体的代理实现
类Proxy
生成代理的具体的操作类,可以为一个or多个接口动态的实现代理类
缺点 就是被代理的类必须是接口的实现类(依赖于接口),
如果某些类没有实现接口 则不能用jdk代理
package Proxy.DynamicProxy.JDKProxy; /**
* 目标接口
*/
public interface UserManager { public void addUser(String name ,String password);
public void detUser(String name);
}
 package Proxy.DynamicProxy.JDKProxy;
 public class UserManagerImpl implements UserManager {
     @Override
     public void addUser(String id, String password) {
         System.out.println("调用了UserManagerImpl.addUser()方法");
     }
     @Override
     public void detUser(String id) {
         System.out.println("调用了UserManagerImpl.detUser()的方法");
     }
 }
package Proxy.DynamicProxy.JDKProxy; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; /**
* JDK动态代理类
*/
public class JDKDynamicProxy implements InvocationHandler {
//需要代理的目标对象
private Object targetObject; public Object newProxy(Object targetObject) {
//将目标对象传入进行代理
this.targetObject = targetObject;
//将代理对象返回 //其中有三个参数
return Proxy.newProxyInstance(
targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(),
this);
} // invoke 测试方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 代理前 :逻辑处理的方法(函数)
checkPopedom();
Object reflect = null;
// 调用invoke()
reflect = method.invoke(targetObject, args);
// 代理后:
isOK();
return reflect;
} private void isOK() {
System.out.println("权限通过:isOK()");
} private void checkPopedom() {
System.out.println("检查权限:checkPopedom()");
} }
package Proxy.DynamicProxy.JDKProxy; /**
* 测试类
*
*/
public class JDKDynamicProxyTest {
public static void main(String[] args) { JDKDynamicProxy jdkDynamicProxy = new JDKDynamicProxy();
//JDK动态代理对象传入一个需要代理的对象 然后用需要代理的对象接收就OK啦
UserManager userManagerJDK = (UserManager) jdkDynamicProxy.newProxy(new UserManagerImpl());
userManagerJDK.addUser("tom","root");
userManagerJDK.addUser("jeck","root");
/**
* 运行结果:
* 检查权限:checkPopedom()
* 调用了UserManagerImpl.addUser方法
* 权限通过:isOK()
* 检查权限:checkPopedom()
* 调用了UserManagerImpl.addUser方法
* 权限通过:isOK()
*/
}
}
cglib
原理是针对target类 生成一个子类 覆盖方法实现增强
缺点 基于继承 无法代理final类(final类无法被继承,如String)
需要的jar包 :asm-3.3.1,cglib-2.2.jar ps:jar包版本不同可能会报错
详细情况请看:www.cnblogs.com/cruze/p/3865180.html#lable1
参看文献:
https://shifulong.iteye.com/blog/2166770
https://www.cnblogs.com/gonjan-blog/p/6685611.html
http://blog.jobbole.com/104433/
https://baike.baidu.com/item/动态代理类/5087985?fr=aladdin
Java的动态代理(DynamicProxy)的更多相关文章
- java的动态代理机制详解
		
在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...
 - java中动态代理
		
一.在java中怎样实现动态代理 1.我们要有一个接口,还要有一个接口的实现类,而这个实现类呢就是我们要代理的对象 接口: package org.dynamicproxy.test; public ...
 - Java的动态代理机制详解(转)
		
在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...
 - (转)java的动态代理机制详解
		
原文出自:http://www.cnblogs.com/xiaoluo501395377/p/3383130.html 在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一 ...
 - [转载] java的动态代理机制详解
		
转载自http://www.cnblogs.com/xiaoluo501395377/p/3383130.html 代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代 ...
 - 深入理解Java反射+动态代理
		
答: 反射机制的定义: 是在运行状态中,对于任意的一个类,都能够知道这个类的所有属性和方法,对任意一个对象都能够通过反射机制调用一个类的任意方法,这种动态获取类信息及动态调用类对象方法的功能称为j ...
 - Spring学习(二)—— java的动态代理机制
		
在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...
 - 【转】java的动态代理机制详解
		
java的动态代理机制详解 在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们 ...
 - java中动态代理实现机制
		
前言: 代理模式是常用的java设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系 ...
 
随机推荐
- Vue组件之间通信的三种方式
			
最近在看梁颠编著的<Vue.js实战>一书,感觉颇有收获,特此记录一些比价实用的技巧. 组件是MVVM框架的核心设计思想,将各功能点组件化更利于我们在项目中复用,这类似于我们服务端面向对象 ...
 - js实现点击上下按钮,图片向上向下循环滚动切换
			
//popup.js //jquery.1.4.2-min.js (function(p,j){function u(){if(!c.isReady){try{v.documentElement.do ...
 - js中关于string转date类型的转换
			
var date_up = input.split("-");//input表示string类型(时间例如:2017-11-12 10:07:36.653) var date_do ...
 - Jmeter接口测试---JDBC简单实践
			
我的环境:MySQL:mysql-5.6.24-win32 jdbc驱动:mysql-connector-java-5.1.22-bin.jar JMeter:apache-jmeter-2.13 1 ...
 - 关于使用 autoFac 的注入方法
			
1.使用 NUGET 安装 Autofac 2.需要引用Autofac ASP.NET MVC 5 Integration 这个扩展包. 但有时候在NuGet中找不到 该包 需要使用“程序要控制器控 ...
 - tensorFlow资源
			
1,[莫烦]Tensorflow tutorials (Eng Sub) 神经网络 http://www.bilibili.com/video/av10118932/index_35.html#pag ...
 - tp登陆注册(转)
			
登录时,更新用户数据,登录ip和登录时间,以及登录次数+1,此实现方便不知是否合适,待验证.源码地址:https://github.com/grh0812/thinkphp-login-registe ...
 - 3星|《OKR:源于英特热和谷歌的目标管理利器》:OKR原理、实施手册、实施过的公司的访谈
			
OKR原理与实施手册,另外附了几家实施过OKR的公司的访谈. 书中表述的OKR思想,我认为是这两点: 1:始终聚焦在最重要的目标上: 2:不以OKR为考核员工的指标: Kindle电子版排版有小缺陷, ...
 - struts2配置文件加载顺序
			
struts2配置文件加载顺序: struts-default.xml/ struts-plugin.xml/ struts.xml/ struts.properties/ web.xml
 - HDU_1227_Fast Food_动态规划
			
链接:http://acm.hdu.edu.cn/showproblem.php?pid=1227 Fast Food Time Limit: 2000/1000 MS (Java/Others) ...