一、动态代理引入

package cn2;public interface IUserDAO {	/**	 * 登录方法	 */	public void login();		/**	 * 注册方法	 */	public void register();}package cn2;public class UserDAOImpl implements IUserDAO {	@Override	public void login() {		System.out.println("用户登录");	}	@Override	public void register() {		System.out.println("用户注册");	}}package cn2;public class Test {	public static void main(String[] args) {		IUserDAO dao = new UserDAOImpl();		dao.register();		dao.login();					}}

用户注册

用户登录

如果我要给每个方法都增加权限校验和日志记录的话,那么代码实现如下:

package cn2;public interface IUserDAO {	/**	 * 登录方法	 */	public void login();		/**	 * 注册方法	 */	public void register();}package cn2;public class UserDAOImpl implements IUserDAO {	@Override	public void login() {		System.out.println("用户登录");	}	@Override	public void register() {		System.out.println("用户注册");	}}package cn2;public class UserDAOImpl2 implements IUserDAO {	private void actionCheck(){		System.out.println("权限检查");	}		private void record(){		System.out.println("日志记录");	}		@Override	public void login() {		this.actionCheck();		System.out.println("登录");		this.record();	}	@Override	public void register() {		this.actionCheck();		System.out.println("注册");		this.record();	}}package cn2;public class Test {	public static void main(String[] args) {		IUserDAO dao = new UserDAOImpl2();		dao.register();		dao.login();					}}

权限检查

注册

日志记录

权限检查

登录

日志记录

为什么要单独写一个类去实现接口,并增加权限校验和日志记录呢?因为我们在设计的时候,要保证对扩展功能开发,对修改代码关闭的原则。我定义了一个新的类去实现接口,就是想扩展原来接口的功能,而不是在原有的实现类上修改。

但是,如果都这样设计,是很可怕的事情,如果需求一旦变更,那我们需要定义好多好多的实现类,太复杂了。怎么办?

在生活中,我们会遇到很多问题,比如:我要租房子,但是我不认识房东,怎么办?找中介。同样的道理,我自己不想在修改代码去增加权限检查和日志记录的功能,那么我找一个代理对象去帮我实现不就可以了吗?

动态代理:就是在程序运行过程中产生的这个对象。

在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口接可以生成动态代理对象。JDK只针对接口做代理。

Proxy类中的方法创建动态代理对象

public static Object newProxyInstance(ClassLoader loader,Class
[] interfaces,InvocationHandler h)

最终会调用InvocationHandler的方法

Object invoke(Object proxy,Method method,Object[] args)
package cn2;public interface IUserDAO {	/**	 * 登录方法	 */	public void login();		/**	 * 注册方法	 */	public void register();}package cn2;public class UserDAOImpl implements IUserDAO {	@Override	public void login() {		System.out.println("用户登录");	}	@Override	public void register() {		System.out.println("用户注册");	}}package cn2;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;	}		/**	 *返回动态代理对象	 */	@Override	public Object invoke(Object proxy, Method method, Object[] args)			throws Throwable {				System.out.println("权限检查");				Object invoke = method.invoke(target, args);				System.out.println("日志记录");		return invoke;	}}package cn2;import java.lang.reflect.Proxy;public class Test {	public static void main(String[] args) {		//使用动态代理之前		IUserDAO dao = new UserDAOImpl();		dao.register();		dao.login();				System.out.println("-------------------");				//使用动态代理之后				IUserDAO proxy = (IUserDAO)Proxy.newProxyInstance(dao.getClass().getClassLoader(), dao.getClass().getInterfaces(), new MyInvocationHandler(dao));		proxy.register();		proxy.login();			}}

用户注册

用户登录

-------------------

权限检查

用户注册

日志记录

权限检查

用户登录

日志记录