`
houlinyan
  • 浏览: 148090 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论
阅读更多

1、JDK的动态代理

 

JDK的动态代理是JDK1.3版的时候提出来的,主要涉及到java.lang.reflect包中的两个类:Proxy和InvocationHandler,其中 InvocationHandler 是一个接口,通过实现接口的横切逻辑,并通过反射机制调用目标代码,将横切逻辑和目标代码 动态编织在一起, Proxy是为InvocationHandler 实现类动态创建一个指定接口的代理示例 举例说明:

 

问题:

 

 业务类:

package aop;

public interface Service {

	public void service(String arg);
}


 

业务实现类:

package aop;

public class ServiceImpl implements Service {

	public void service(String arg) {
		
		System.out.println("service is called,arg : "+arg);

	}

}

 

 

 想在执行Service的service方法的前后加入PerformanceMonitor的begin和end,PerformanceMonitor 如下:

 

package aop;

public class PerformanceMonitor {

	public static void  begin(){
		System.out.println("监控开始");
	}
	
	public static void end(){
		System.out.println("监控结束");
	}
}

 

即在执行service之前调用begin方法,执行完成之后调用end方法

 

动态代理解决方案如下:

需要添加一个ServiceHandler类如下:

 

package aop;

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

public class ServiceHandler implements InvocationHandler {

	private Object target ;
	
	public ServiceHandler(Object target){
		this.target = target;
	}
	
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
	    PerformanceMonitor.begin();
		Object obj = method.invoke(target, args);
		PerformanceMonitor.end();
		return obj;
	}

}

 

动态代理的关键是这个地方,需要注意一下几点:

1、需要实现InvocationHandler

2、在invoke方法里面,实现动态代理,

    method是要被调用的方法,这还代码

  

Object obj = method.invoke(target, args);

   就是调用的业务,动态代码就是要在这行的前后加上调用前和调用后的处理

   也即是 PerformanceMonitor.begin();和 PerformanceMonitor.end();
3、必须要知道调用的是那个实例的方法,所以需要构造器把实例传进去

 

好了,现在可以写测试类测试了:

package aop;

import java.lang.reflect.Proxy;

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Service service = new ServiceImpl();
		ServiceHandler serviceHandler= new ServiceHandler(service);
		Service proxy = (Service) Proxy.newProxyInstance(service.getClass()
				.getClassLoader(), service.getClass().getInterfaces(), serviceHandler);

		proxy.service("1111111111111");
	}

}

 

 

  看到测试类,你应该就明白了原理了,Proxy负责生成一个代理的实例,这个实例在调用service方法的时候,改成了调用serviceHandler的invoke方法,从而把begin和end的动作插入。

测试结果如下:

 

监控开始
service is called,arg : 1111111111111
监控结束

 

好了,JDK的动态代理还是蛮简单的哈!

另,附件aop.zip中包含有全部的代码,直接可以运行

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics