JDK与CGlib动态代理的实现
应用的原型为
执行者:房屋中介Agency(分为JDKAgency、CGlibAgency)
被代理对象:程序员Programmer
被代理对象的实现接口:租户Tenement(CGlibAgency时不需要实现接口)
Tenement 接口:
package com.suzao.spring.test; /**
* Tenement
* @Description 租户
* @Param
* @return
* @Author mc
* @Date 2018/12/28 16:44
*/
public interface Tenement { /**
* rentHouse
* @Description 租房方法
* @Param []
* @return
* @Author mc
* @Date 2018/12/28 18:51
*/
void rentHouse();
}
Programmer 实现类
package com.suzao.spring.test; /**
* Programmer
* @Description 程序员
* @Param
* @return
* @Author mc
* @Date 2018/12/28 18:21
*/
public class Programmer implements Tenement { /**
* rentHouse
* @Description 租房方法
* @Param []
* @return
* @Author mc
* @Date 2018/12/28 18:52
*/
@Override
public void rentHouse() {
System.out.println("我是程序员,我在找房子!");
}
}
JDK动态代理:执行者 JDKAgency
package com.suzao.spring.test; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; /**
* JDKAgency
* @Description JDK房屋中介
* @Param
* @return
* @Author mc
* @Date 2018/12/28 18:22
*/
public class JDKAgency implements InvocationHandler{ //拿到被代理对象的引用
private Tenement target; public Object getTenementProxy(Tenement target){
this.target = target;
Class clazz = target.getClass();
//clazz.getInterfaces() 获取它的接口
//重新动态生成一个class字节码
//编译
return Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this);
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("JDK房屋中介开始执行。。。");
System.out.println("----------------------------");
method.invoke(this.target,args);
System.out.println("----------------------------");
System.out.println("JDK房屋中介结束执行。。。");
return null;
}
}
CGlib动态代理:执行者 CGlibAgency
package com.suzao.spring.test; import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; /**
* CGlibAgency
* @Description CGlib 租房中介
* @Param
* @return
* @Author mc
* @Date 2018/12/28 19:11
*/
public class CGlibAgency implements MethodInterceptor{ public Object getTenmentProxy(Class clazz){ Enhancer enhancer = new Enhancer(); //告诉cglib,生成的子类需要继承那个类
enhancer.setSuperclass(clazz); //设置回调
enhancer.setCallback(this); //加载到jvm中,并返回代理对象
return enhancer.create();
} @Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("CGlib房屋中介开始执行。。。");
System.out.println("----------------------------");
methodProxy.invokeSuper(obj,args);
System.out.println("----------------------------");
System.out.println("CGlib房屋中介结束执行。。。");
return null;
}
}
代理测试类 TestProxy
package com.suzao.spring.test; /**
* TestProxy
* @Description 测试代理
* @Param
* @return
* @Author mc
* @Date 2018/12/28 18:46
*/
public class TestProxy { public static void main(String[] args) { //java动态代理是利用反射机制生成一个实现被代理对象的接口的匿名类,在调用具体方法前调用InvokeHandler来处理。 //执行者 JDKAgency
//被代理对象 Programmer
//被代理对象实现的接口 Tenement
Tenement tenement= (Tenement) new JDKAgency().getTenementProxy(new Programmer());
tenement.rentHouse();
System.out.println("\n\n"); //cglib动态代理利用asm开源包,对被代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
//执行者 CGlibAgency
//被代理对象 Programmer
Programmer programmer= (Programmer) new CGlibAgency().getTenmentProxy(new Programmer().getClass());
programmer.rentHouse();
}
}
执行结果:
JDK房屋中介开始执行。。。
----------------------------
我是程序员,我在找房子!
----------------------------
JDK房屋中介结束执行。。。 CGlib房屋中介开始执行。。。
----------------------------
我是程序员,我在找房子!
----------------------------
CGlib房屋中介结束执行。。。
pom.xml中引用:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
</dependency>
JDK与CGlib动态代理的实现的更多相关文章
- 动态代理的两种方式,以及区别(静态代理、JDK与CGLIB动态代理、AOP+IoC)
Spring学习总结(二)——静态代理.JDK与CGLIB动态代理.AOP+IoC 目录 一.为什么需要代理模式 二.静态代理 三.动态代理,使用JDK内置的Proxy实现 四.动态代理,使用cg ...
- Spring AOP中的JDK和CGLib动态代理哪个效率更高?
一.背景 今天有小伙伴面试的时候被问到:Spring AOP中JDK 和 CGLib动态代理哪个效率更高? 二.基本概念 首先,我们知道Spring AOP的底层实现有两种方式:一种是JDK动态代理, ...
- 【java高级编程】JDK和CGLIB动态代理区别
转载:https://blog.csdn.net/yhl_jxy/article/details/80635012 前言 JDK动态代理实现原理(jdk8):https://blog.csdn.net ...
- JDK、CGlib动态代理详解
Java动态代理之JDK实现和CGlib实现(简单易懂) 一 JDK和CGLIB动态代理原理 1.JDK动态代理 利用拦截器(拦截器必须实现InvocationHanlder)加上反射机制生 ...
- JDK和CGLIB动态代理区别
背景:虽然自己了解这两种代理的区别,但是面试时候还是答的很模糊,需要好好总结. 前言JDK动态代理实现原理(jdk8):https://blog.csdn.net/yhl_jxy/article/de ...
- JDK和CGLIB动态代理原理
1.JDK动态代理利用拦截器(拦截器必须实现InvocationHanlder)加上反射机制生成一个实现代理接口的匿名类, 在调用具体方法前调用InvokeHandler来处理. 2.CGLiB动态代 ...
- JDK和CGLIB动态代理原理区别
JDK和CGLIB动态代理原理区别 https://blog.csdn.net/yhl_jxy/article/details/80635012 2018年06月09日 18:34:17 阅读数:65 ...
- Spring框架中的JDK与CGLib动态代理
JDK和CGLib动态代理区别 JDK动态代理:利用拦截器(拦截器必须实现InvocationHanlder)加上反射机制生成一个实现代理接口的匿名类, 在调用具体方法前调用InvokeHandler ...
- spring框架中JDK和CGLIB动态代理区别
转载:https://blog.csdn.net/yhl_jxy/article/details/80635012 前言JDK动态代理实现原理(jdk8):https://blog.csdn.net/ ...
- jdk和cglib动态代理
一.原理区别:java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理. 而cglib动态代理是利用asm开源包,对代理对象类的class文件加 ...
随机推荐
- TimeUtil 工具类
/** * TODO * * @auther xh * @date 6/11/19 3:32 PM */ public class TimeUtil { public static final Str ...
- 如何对Linux内核参数进行优化?
打开配置文件 vi /etc/sysctl.conf 输入配置,如下是内核优化的参数 # TCP三次握手建立阶段接收SYN请求队列的最大长度,默认为1024(将其设置得大一些可以使出现Nginx繁忙来 ...
- 15.Filter(过滤器)
1.管理所有WEB资源:(Jsp, Servlet, 静态图片文件或静态 html 文件等)文件等进行拦截,从而实现一些特殊的功能 2.Filter接口中有一个doFilter方法,当我们编写好Fil ...
- docker images 导入和导出
目录 docker images 导入和导出 1.前言 2.docker image 的保存 3.docker image 的导入 docker images 导入和导出 1.前言 前提是现在有一个可 ...
- Win8电脑更新出现错误代码80070003的解决方法
有Win8系统用户在进行KB2894853更新时会碰到系统报错的问题,错误代码是80070003,那么在遇到这个问题的时候,我们该怎么去解决呢?下面好系统U盘启动就来告诉你相应的解决方法. Win8系 ...
- linux在配置菜单中添加选项
- python 之math模块
一.math 简介 import math # 导入模块 ret = dir(math) # 查看所有函数名列表 print(ret) # ['__doc__', '__loader__', '__n ...
- shell读取或者修改ini文件
cfg_find(){ file_name=$1 labelname=$2 key=$3 labelline=$(grep -n "^\[.*\]$" $file_name | a ...
- 注意条件表达式规范[JLS 15.25]
/** * 猜猜输出结果是什么 */ public class appalet { public static void main(String[] args) { char x = 'x'; int ...
- javascript只弹出一次框 再次刷新不弹出
.打开页面自动弹出 当关闭弹框的时候 设置cookie生存时间 再次刷新页面判断cookie是否失效 <html> <head> <meta charset=&qu ...