使用 jdk Proxy 生成动态代理

java类说明:
ITestProxyService.java 使用jdk动态代理,要实现的接口。
TestProxyServiceImpl.java 接口的本地实现类。
MyInvocationHandler.java 使用jdk动态代理 目标类。
TestProxyExecute.java 调用动态代理,进行测试。

package com.koolearn.demo.proxy.jdk;


/**

 * 测试动态代理的实现类
 *
 */
public class TestProxyServiceImpl implements ITestProxyService {

	@Override
	public String test(String param) {
		
		System.out.println("TestProxyServiceImpl.test() execute.......param is :"+param);

		return "test_"+System.currentTimeMillis();
	}

	@Override
	public String notExecuete() {
		
		System.out.println("TestProxyServiceImpl.notExecuete() execute.......");
		
		return "notExecute ....";
	}
	
	

}

package com.koolearn.demo.proxy.jdk;/** * * 测试动态代理的接口 * */public interface ITestProxyService {public String test(String param);public String notExecuete();}

package com.koolearn.demo.proxy.jdk;

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

/**
 * 测试 jdk 的动态代理:
 * 实现自己的InvocationHandler
 */
public class MyInvocationHandler implements InvocationHandler {

	 //目标对象(接口的原实现类)   
	private Object target;
	
    /** 
     * 构造方法 :通过构造方法,传入目标对象。
     * @param target 目标对象  
     */   
	public MyInvocationHandler(Object target){
		super();
		this.target=target;
	}
	
	/** 
     * 执行目标对象的方法 :通过 method.invoke(target, args); 方式进行调用。
     * @param proxy:指被代理的对象
     * @param method: 要调用的方法
     * @param args:方法调用时所需要的参数 
     * 
     */  
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		
		//可以根据方法名称,来进行过滤:只对部分方法执行代理。
		if(!method.getName().equals("test")){
			System.out.println(method.getName()+"方法,不执行代理。只针对 test 方法执行代理");
			return null;
		}
		
		System.out.println("当前正在运行的方法:"+method.getName());
		
		//代理方法执行之前 
		System.out.println("---------------  before -----------");
		
		//执行目标对象的方法 
		//实际就是通过反射,获取到了 Method 对象,然后通过调用 method.invoke(正常的通过反射调用method的形式:method.invoke(obj,args...))
		Object result = method.invoke(target, args);
		
		
		//代理方法执行之后
		System.out.println("---------------  after -----------");
		
		//为了测试获取方法的返回值
		System.out.println("方法执行后的结果:"+result);
		return result;
	}

	/** 
     * 获取目标对象的代理对象。通过这个方法,才能获取到代理对象。(在TestProxyExecute 中,调用语句为: hander.getProxy();)
     * @return 代理对象 (会重新生成接口的实现)
     */  
	public Object getProxy(){
		return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), target.getClass().getInterfaces(), this);
	}
}

package com.koolearn.demo.proxy.jdk;


/**
 * 调用动态代理。使用前提:被代理的对象必须实现了某个接口。--比较有局限性。 
* 自定义动态代理步骤:
* ①:实现 InvocationHandler 接口,并覆写其中的 invoke 方法。
* 其中 Method method 对象就是当前执行的方法;
* Object[] args 是执行方法的所有参数。
* ②:实例化接口对象 interface。
* ③:实例化自定义的MyInvocationHandler对象,并将接口对象传入到 MyInvocationHandler 对象。
* ④:生成代理对象。(也就是根据 MyInvocationHandler 生成新的 interface 实现)
* ⑤:通过代理对象,调用指定的代理方法。(也就是ITestProxyService 的 test() 方法 )
* * */ public class TestProxyExecute { public static void main(String[] args) { // 实例化目标对象 ITestProxyService service = new TestProxyServiceImpl(); // 实例化InvocationHandler MyInvocationHandler hander = new MyInvocationHandler(service); // 根据目标对象生成代理对象 ITestProxyService proxy = (ITestProxyService)hander.getProxy(); // 调用代理对象的方法 proxy.test("hello,word"); //测试其他方法: proxy.notExecuete(); } public void testGrenetProxyClass(){ } }

执行结果:

当前正在运行的方法:test
---------------  before -----------
TestProxyServiceImpl.test() execute.......param is :hello,word
---------------  after -----------
方法执行后的结果:test_1407138249607
notExecuete方法,不执行代理。只针对 test 方法执行代理


你可能感兴趣的:(jdk,proxy,动态代理)