面向AOP编程 一 动态代理

本文详细介绍了Java动态代理与Cglib的基本原理、实现方式及优缺点,包括代理类生成、日志切面类应用以及性能影响分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
 * JDK 实现的动态代理    打印日志切面类 
 */
public class LogInvocationHandler implements InvocationHandler {

	public static void main(String[] args) {

		// 需要代理的接口,被代理类实现的多个接口都必须在这里定义
		Class[] proxyInterface = new Class[] { IBusiness.class,
		IBusiness2.class };

		// 构建AOP的Advice,这里需要歘如业务的实例
		LogInvocationHandler handler = new LogInvocationHandler(new Business());

		// 生成代理类的字节码加载器
		ClassLoader classLoader = LogInvocationHandler.class.getClassLoader();

		// 织入器,织入代码并生成代理类
		IBusiness2 proxyBusiness = (IBusiness2) Proxy.newProxyInstance(
		classLoader, proxyInterface, handler);

		//使用代理类的实例调用方法
		proxyBusiness.doSomeThing2();
		((IBusiness)proxyBusiness).doSomeThing();

	}

	private Object target;// 目标对象

	LogInvocationHandler(Object target) {
		this.target = target;
	}

	public Object invoke(Object proxy, Method method, Object[] args)
	throws Throwable {
		// 执行原有的逻辑
		Object rev = method.invoke(target, args);

		// 执行织入的日志,你可以控制那些方法执行切入逻辑
		if (method.getName().equals("doSomeThing2")) {
		System.out.println("记录日志");
		}

		return rev;
	}

}

interface IBusiness {
	public boolean doSomeThing();
}

interface IBusiness2 {
	public boolean doSomeThing2();
}

class Business implements IBusiness, IBusiness2 {

	public boolean doSomeThing() {
		System.out.println("执行业务逻辑");
		return false;
	}

	public boolean doSomeThing2() {
		System.out.println("执行业务逻辑2");
		return false;
	}

}

动态代理的核心其实就是代理对象的生成,即Proxy.newProxyInstance(classLoader, proxyInterface, handler)

    动态代理在运行期通过接口动态生成代理类,这为其带来了一定的灵活性,
但这个灵活性却带来了两个问题,第一代理类必须实现一个接口,
如果没实现接口会抛出一个异常。第二性能影响,因为动态代理使用反射的机制实现的,

    首先反射肯定比直接调用要慢,经过测试大概每个代理类比静态代理多出10几毫秒的消耗。
    其次使用反射大量生成类文件可能引起Full GC造成性能影响,
       因为字节码文件加载后会存放在JVM运行时区的方法区(或者叫持久代)中,
       当方法区满的时候,会引起Full GC,所以当你大量使用动态代理时,
       可以将持久代设置大一些,减少Full GC次数。

 

CgLib 实现动态代理

 

/**
 * Cglib是一个强大的,高性能的Code生成类库,
 * 它可以在运行期间扩展Java类和实现Java接口,
 * 它封装了Asm,所以使用Cglib前需要引入Asm的jar
 */
public class LogIntercept implements MethodInterceptor{

	public static void main(String[] args) {
		//创建一个织入器
		Enhancer enhancer = new Enhancer();
		//设置父类
		enhancer.setSuperclass(Business.class);
		//设置需要织入的逻辑
		enhancer.setCallback(new LogIntercept());
		//使用织入器创建子类
		IBusiness2 newBusiness = (IBusiness2)enhancer.create();
		newBusiness.doSomeThing2();
		((IBusiness)newBusiness).doSomeThing();
	}
	
	public Object intercept(Object target, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {
		//执行原有逻辑,注意这里是invokeSuper
		Object rev = proxy.invokeSuper(target, args);
		
		//执行织入的日志
		if (method.getName().equals("doSomeThing2")) {
			System.out.println("记录日志");
		}
		return rev;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值