SpringAOP(二) 利用动态代理实现横切逻辑

        原始的性能监控功能中性能监控的代码和业务层代码混合在一起,当某个方法需要进行性能监控,就必须调整方法代码,在方法的前面后面加上性能监控代码,这些非业务逻辑的性能监控代码破坏了业务逻辑的纯粹性。

        我们可以通过动态代理来实现两者分离,一种是jdk自带的动态代理,但是只能是创建接口的动态代理,还有一种是CGlib动态代理,可以创建实现类的代理

        首先利用jdk实现动态代理,修改原来的代码

       1、业务代码中删除性能监控代码,只留模拟删除的功能


package com.test.proxy;

/**
 * @author Administrator
 *
 */
public interface ForumService 
{
	 void removeTopic(int topic);
	
	 void removeMessage(int messageId);
}


/**
 * 
 */
package com.test.proxy;

/**
 * 
 *  业务类
 * @author Administrator
 *
 */
public class ForumServiceImpl implements ForumService
{
	@SuppressWarnings("static-access")
	public void removeTopic(int topic)
	{
		
		System.out.println("模拟删除topic记录"+topic);
		
		try
		{
			Thread.currentThread().sleep(20);
		}
		catch(Exception e)
		{
			throw new RuntimeException(e);
		}
		
	}
	
	@SuppressWarnings("static-access")
	public void removeMessage(int messageId)
	{
		System.out.println("模拟删除messageId记录"+messageId);
		
		try
		{
			Thread.currentThread().sleep(40);
		}
		catch(Exception e)
		{
			throw new RuntimeException(e);
		}
	}
}


2、新建一个自定义Handler


/**
 * 
 */
package com.test.proxy;

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

/**
 * @author Administrator
 *
 */
public class PerformanceHandler implements InvocationHandler 
{
	//obj 为业务实例
	private Object target;
	
	public PerformanceHandler(Object target)
	{
		this.target = target;
	}
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable 
	{
		PerformanceMonitor.begin(target.getClass().getName()+"."+method.getName());
		
		//通过反射调用业务的目标方法
		Object obj = method.invoke(target, args);
		PerformanceMonitor.end();
		return obj;
	}

}


3、测试类


/**
 * 
 */
package com.test.proxy;

import java.lang.reflect.Proxy;

/**
 * @author Administrator
 *
 */
public class TestForumService 
{
	public static void main(String[] args) {
		ForumService forumService = new ForumServiceImpl();//希望被代理的业务类
		
		PerformanceHandler handler = new PerformanceHandler(forumService); //讲目标业务和横切代码(性能监控)编制在一起
		
		ForumService proxy = (ForumService)Proxy.newProxyInstance(forumService.getClass().getClassLoader(),forumService.getClass().getInterfaces(),handler);
		
		proxy.removeTopic(10);
		
		proxy.removeMessage(20);
		
	}
}


4、运行结果

begin monitor
模拟删除topic记录10
end monitor
com.test.proxy.ForumServiceImpl.removeTopic花费20毫秒.
begin monitor
模拟删除messageId记录20
end monitor
com.test.proxy.ForumServiceImpl.removeMessage花费40毫秒.


总结:

        使用动态代理,就是建立一个编织器,例如此处的PerformanceHandler,将业务代码和性能监控的代码编织在一起了,而两边的代码都各自独立,相互不影响。

既然是代理,肯定知道用了反射的技术。


缺点:

1、目标业务类的所有方法都加了性能监控横切逻辑,有时候可能只需要对某些特定的方法实现横切逻辑

2、通过硬编码指定了织入横切逻辑的切入点,即在目标业务方法的开始前和开始后织入代码

3、在测试代码中,手工编写代理实例的创建,为不同类创建代理时,需要分别创建相应的Handler,无法通用




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值