码迷,mamicode.com
首页 > 编程语言 > 详细

java之动态代理

时间:2016-11-30 23:31:33      阅读:202      评论:0      收藏:0      [点我收藏+]

标签:java之动态代理

一、动态代理引入

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();
		
	}
}

用户注册

用户登录

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

权限检查

用户注册

日志记录

权限检查

用户登录

日志记录




本文出自 “11831428” 博客,请务必保留此出处http://11841428.blog.51cto.com/11831428/1878267

java之动态代理

标签:java之动态代理

原文地址:http://11841428.blog.51cto.com/11831428/1878267

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!