博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
实现:JDK动态代理和CGLIB动态代理
阅读量:3906 次
发布时间:2019-05-23

本文共 3006 字,大约阅读时间需要 10 分钟。

可以参看我的另外一篇博客,了解一下静态代理和动态代理:

JDK动态代理

JDK动态代理只能对实现了接口的类生成代理,而不能针对类;实现InvocationHandler接口,重写invoke()方法。

 

模拟链家找房子

1. 接口

定义一个方法,searchHouse(),找房子

/** * 接口 * @author 75736 * */public interface Person {	 void searchHouse(); }

2. 目标类

目标类实现接口,重写接口方法

/** * 目标类 * 实现接口 * @author 75736 * */public class Master implements Person {	@Override	public void searchHouse() {       System.out.println("找房子");	}}

3. 代理类

代理类持有对目标对象的引用

/** * 代理类 * 持有目标类的引用 * @author 75736 * */public class HomeLink implements InvocationHandler{	 private Person target;   // 代理对象	    	 	/**	 	 * 初始化代理对象	 	 * @param target	 	 * @return	 	 */	    public Object getInstance(Person target){	        this.target = target;	        Class clazz = target.getClass();	        	        // static Object newProxyInstance(ClassLoader loader, Class
[] interfaces, InvocationHandler h) // loader:指明代理对象使用哪个类加载器,代理类的类加载器 // interfaces:用来指明生成哪个对象的代理对象,通过接口指定,代理类实现的接口 // h:用来指明产生的这个代理对象要做什么事情,代理对象 Object obj = Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this); return obj; } @Override public Object invoke(Object obj, Method method, Object[] args) throws Throwable { System.out.println("我是链家,我帮别人找房子.."); // invoke(obj, args) // target:也就是被代理类的对象 // args:方法中的参数 method.invoke(target, args); System.out.println("我是链家,已经找完了.."); return null; }}

4. 测试

public class TestSearchHouse {	public static void main(String[] args) {		// 获取代理对象实例		Person person = (Person) new HomeLink().getInstance(new Master());				person.searchHouse();	}}

CGLIB动态代理

        CGLIB是针对类实现代理,其原理是通过目标类的字节码为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。

1. 目标类

/** * 目标类 * 没有可实现的父接口 * @author 75736 * */public class Master{	public void searchHouse() {       System.out.println("找房子");	}}

2. 代理类

/** * 代理类  * 原理: 通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑 *  * @author 75736 * */public class HomeLink implements MethodInterceptor {	// net.sf.cglib.proxy.Enhancer:主要增强类,通过字节码技术动态创建委托类的子类实例;	private Enhancer enhancer = new Enhancer();	/**	 * 获取代理对象	 * 	 * @param clazz	 * @return	 */	public Object getProxy(Class clazz) {		// 进行代理,设置需要创建子类的类		enhancer.setSuperclass(clazz);		// 设置织入逻辑		enhancer.setCallback(this);		// 生成代理实例,通过字节码技术动态创建子类实例		return enhancer.create();	}	/**	 * 实现MethodInterceptor接口方法 实现具体拦截处理 	 * @param obj:动态生成的代理对象 	 * @param method : 实际调用的方法 	 * @param args:调用方法入参	 * @param proxy:java Method类的代理类,可以实现委托类对象的方法的调用	 */	@Override	public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {		System.out.println("前置代理");		// 通过代理类调用父类中的方法		Object result = proxy.invokeSuper(obj, args);		System.out.println("后置代理");		return result;	}}

3. 测试

public class TestSearchHouse {	public static void main(String[] args) {		HomeLink proxy = new HomeLink();		// 通过生成子类的方式创建代理类		Master proxyImp = (Master) proxy.getProxy(Master.class);		proxyImp.searchHouse();  // 调用intercept方法	}}

 

转载地址:http://hsqen.baihongyu.com/

你可能感兴趣的文章
xrange vs range python
查看>>
None Python
查看>>
Naive Pattern Searching
查看>>
Sales Engineer
查看>>
US Shirt Size
查看>>
recursive tree
查看>>
An Introduction to Python Lists
查看>>
gstack - stack trace of a running process
查看>>
strace
查看>>
Mac OS X Install Docker
查看>>
Quickstart containers
查看>>
About the Docker Hub
查看>>
About Docker
查看>>
Hello world in a container
查看>>
Run a simple application
查看>>
Build Your Own Images
查看>>
Networking Containers
查看>>
Manage Data in Containers
查看>>
Docker Swarm Overview
查看>>
Overview of Docker Compose
查看>>