Java动态代理

Java的动态代理分为两种:

1、基于原生Java API实现,依赖于反射机制;

要点:

A、被代理类必须实现接口

B、代理处理类要实现接口:java.lang.reflect.InvocationHandler,实现invoke方法,通过反射方式完成逻辑调用,同时可以分装入前置、后置的代理逻辑;

C、通过Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this)获取代理对象;

2、cglib提供的基于修改字节码的方式实现,底层依赖于asm字节码处理包,基本逻辑是:基于现有类的class,生成其子类,然后再针对子类方法做代理调用;

要点:

A、被代理类可以不用实现接口;

B、依赖于cglib包;

3、代理处理类要实现接口:net.sf.cglib.proxy.MethodInterceptor,实现intercept方法,通过反射完成逻辑调用,同样可以增加自己的增强代码;

3、通过net.sf.cglib.proxy.Enhancer对象来构造新代理对象,其中,需要指定父类、回调类;

 

应用场景:日志、事务等无侵入式的AOP代理切入;

 

示例代码:

1、要被代理的业务逻辑类

/**
 * 业务逻辑接口
 */
public interface IBusinessService {
	void business();
}


/**
 * 业务逻辑类
 */
public class BusinessServiceImpl implements IBusinessService {

	public void business() {
		System.out.println("我是业务逻辑");
	}
}

2、JDK动态代理类

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 基于JDK的动态代理
 */
public class JdkProxy implements InvocationHandler {

	private Object targetObject;

	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("JdkProxy代理开始");
		Object resultObj = method.invoke(targetObject, args);
		System.out.println("JdkProxy代理结束");
		return resultObj;
	}

	public Object getObject(Object obj) {
		this.targetObject = obj;
		return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
	}

}

3、CGLIB动态代理类

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

/**
 * 基于cglib的动态代理
 */
public class CglibProxy implements MethodInterceptor {

	private Object targetObject;

	public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
		System.out.println("CglibProxy代理开始");
		Object resultObj = method.invoke(targetObject, args);
		System.out.println("CglibProxy代理结束");
		return resultObj;
	}

	public Object getObject(Object obj) {
		this.targetObject = obj;
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(obj.getClass());
		enhancer.setCallback(this);
		return enhancer.create();
	}
}

4、测试类

import upup.snail.dynamicproxy.cglib.CglibProxy;
import upup.snail.dynamicproxy.jdk.JdkProxy;

/**
 *
 */
public class DynamicProxyTest {

	public void testCglibProxy() {
		CglibProxy cglibProxy = new CglibProxy();
		IBusinessService businessService = (IBusinessService) cglibProxy.getObject(new BusinessServiceImpl());
		businessService.business();
	}

	public void testJdkProxy() {
		JdkProxy jdkProxy = new JdkProxy();
		IBusinessService businessService = (IBusinessService) jdkProxy.getObject(new BusinessServiceImpl());
		businessService.business();
	}

	public static void main(String[] args) {
		DynamicProxyTest dpt = new DynamicProxyTest();
		dpt.testJdkProxy();
		System.out.println();
		dpt.testCglibProxy();
	}
}

输出结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值