java动态代理记录

首先,上代码

BaseJDKProxy.java

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

public abstract class BaseJDKProxy implements InvocationHandler{
	
	protected Object target;

	public BaseJDKProxy(Object target) {
		super();
		this.target = target;
	}
	
	@Override
	public abstract Object invoke(Object proxy, Method method, Object[] args) throws Throwable;

	/**
	 * 获取目标对象的代理对象
	 * @return 代理对象
	 */
	@SuppressWarnings("unchecked")
	public <T> T getProxy() {
		return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
				target.getClass().getInterfaces(), this);
	}
	
	public void before(){
		System.out.println("方法执行前操作.......");
	}
	
	public void after(){
		System.out.println("方法执行后操作.......");
	}
	
	public void err(Exception e){
		// 获取抛出异常信息的代码行数
		System.out.println("调用类:" + Thread.currentThread().getStackTrace()[2].getFileName() + ",行数:" + Thread.currentThread().getStackTrace()[2].getLineNumber());
		System.out.println("方法执行异常,异常信息:" + e);
	}
}

然后是JDKProxy.java

import java.lang.reflect.Method;

public class JDKProxy extends BaseJDKProxy {

	public JDKProxy(Object target) {
		super(target);
		// TODO Auto-generated constructor stub
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		try{
			before();
			System.out.println("-------------------------------------------");
			// 获取代理的方法执行后的返回结果
			// 执行方法(此处不能直接写proxy,原因自己试试就知道了)
			Object result = method.invoke(target, args);
			System.out.println("该方法返回值为:" + result.toString() + "\n-------------------------------------------");
			after();
			return result;
		} catch (Exception e) {
			err(e);
		}
		return null;
	}

}
其次就是代理类以及入口相关

public class JDKProxyTest {
	public static void main(String[] args) {
		LoginService login = new Login();
		JDKProxy proxy = new JDKProxy(login);
		LoginService loginProxy = proxy.getProxy();
		loginProxy.login();
	}
	
}

class Login implements LoginService{
	@Override
	public void login() {
		System.out.println("登录成功");
	}
}

interface LoginService{
	void login();
}

运行后输出日志如下:

运行输出:

方法执行前操作.......
-------------------------------------------
登录成功
调用类:JDKProxy.java,行数:24
方法执行异常,异常信息:java.lang.NullPointerException

修改代码为无异常代码输出:

方法执行前操作.......
-------------------------------------------
登录成功
该方法返回值为:方法无返回
-------------------------------------------
方法执行后操作.......

当然,判断方法是否有返回值之类的可以自行在method中寻找,提供了很多种方法,反射相关,这里不提及

以上便是JDK自带的动态代理实现方式,注意点是被代理的类必须实现了接口

当然,这只是给一个方法添加单个动态代理,下一篇再继续讲如何添加多个动态代理(非官方形式)



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章