JDK动态代理

概述:

java提供的动态代理技术允许开发者在运行期间创建接口的代理实例,这个动态代理必须的基于接口才能使用,主要设计到java.lang.reflect包下的两个类:Proxy和InvocationHandler,其中InvocationHandler是个接口,可以通过实现该接口定义横切逻辑,并通过反射机制调用目标代码,动态将横切逻辑和业务逻辑编织在一起。JDK的动态代理技术在Spring框架中也有使用。

下面是JDK动态代理的一个实例,涉及到一个接口,接口的实现类,一个InvocationHandler接口的实现类,以及一个测试类:



IStudentService接口:
package cn.qing.java.reflect;

public interface IStudentService {

	public String findStudent(String stuName);
	
	public int findStudentNum();
}

StudentServiceImpl接口实现类:
package cn.qing.java.reflect;

public class StudentServiceImpl implements IStudentService {

	public String findStudent(String stuName) {
		System.out.println("findStudent method....");
		return "name:\t"+stuName;
	}

	public int findStudentNum() {
		System.out.println("findStudentNum method ...");
		return 20;
	}

}

MyInvocationHandler类:
package cn.qing.java.reflect;

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

public class MyInvocationHandler implements InvocationHandler {
	private Object target;
	
	public MyInvocationHandler(Object target)
	{
		this.target = target;
	}

	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		
		System.out.println("befor execute method:"+method.getName());
		System.out.println("可以在这里添加一些前置操作....");
		
		//通过反射技术调用具体的方法
		Object obj = method.invoke(target, args);
		
		System.out.println("after execute method:"+method.getName());
		System.out.println("可以在这里添加一些后置操作....");
		return obj;
	}

}
测试类TestProxy:
package cn.qing.java.reflect;

import java.lang.reflect.Proxy;

public class TestProxy {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		TestProxy tp = new TestProxy();
		IStudentService ss = tp.getIStudentServiceInstance();
		ss.findStudent("xiaoming");
		System.out.println("*****************************");
		ss.findStudentNum();
	}
	/**
	 * 通过JDK动态代理返回IStudentService代理对象
	 * @return
	 */
	public IStudentService getIStudentServiceInstance()
	{
		StudentServiceImpl ssi = new StudentServiceImpl();
		//通过Proxy来创建IStudentService代理对象,newProxyInstance方法第二个参数是被代理实现类的接口数组
		//所以JDK的动态代理必须基于接口,不能基于类进行代理
		IStudentService service = (IStudentService)Proxy.newProxyInstance(ssi.getClass().getClassLoader(),
									ssi.getClass().getInterfaces(), new MyInvocationHandler(ssi));
		return service;
	}

}

运行结果:
befor execute method:findStudent
可以在这里添加一些前置操作....
findStudent method....
after execute method:findStudent
可以在这里添加一些后置操作....
*****************************
befor execute method:findStudentNum
可以在这里添加一些前置操作....
findStudentNum method ...
after execute method:findStudentNum
可以在这里添加一些后置操作....

从输出的打印信息中可以看出,在使用得到的代理对象执行具体的方法时,会在方法执行前后执行我们在InvocationHandler实现类中添加的前置或后置实现代码。这样的操作可以运用在我们在执行业务操作的方法前添加一些监视代码,达到监视程序运行状况的效果。很多业务场景都可以用到,比如在Spring的AOP中就使用了JDK的动态代理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值