今天要和大家分享的Java开发知识是Java反射实现动态代理的具体方法。
为什么要写动态代理类?
如果现在想做个登陆注册的功能。用户可以执行登陆、注册、添加、删除这些功能。
但是,有些功能是要有一定权限才可以执行的。
而现在已经有了个用户类的接口和该类的实现类了,但里面没有添加 “权限查询”和“日志记录”这两个功能。
这个时候我不可能去改动这两个类,而且,我以后遇到类似的情况,也不想重复改动。(不想原来的类做,让别的类帮它们做)
那么,我就可以写一个动态代理类和执行类
Java反射实现动态代理的具体方法:
代码:
A:用户的接口类
/* 用户操作接口 */
public interface UserDao {
public abstract void add();
public abstract void delete();
public abstract void update();
public abstract void find();
}
B:用户接口的实现类(模拟功能)
public class UserDaoImpl implements UserDao {
public void add() {
System.out.println("添加功能");
}
public void delete() {
System.out.println("删除功能");
}
public void update() {
System.out.println("修改功能");
}
public void find() {
System.out.println("查找功能");
}}
C:动态代理类
/** 这是对实现用户操作之前的权限检查的动态代理类 */
//注意:创建这个类要实现动态代理接口 InvocationHandler
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("模拟判断权限");
// Object invoke(Object proxy,Method method,Object[]
// args):在代理实例上处理方法调用并返回结果。
Object ob = method.invoke(target, args);
System.out.println("模拟日志记录");
return ob;
}}
D:执行类
public class Test {
public static void main(String[] args) {
// 创建UserDao的实现类对象
UserDao ud = new UserDaoImpl();
// 我们要创建一个动态代理对象
// Proxy类中有一个方法可以创建动态代理对象
// public static Object newProxyInstance(ClassLoader loader,Class[]
// interfaces,InvocationHandler h)
// 对ud对象做一个代理对象
MyInvocationHandler mh = new MyInvocationHandler(ud);
// 创建一个动态代理对象,本来这个方法返回的是Object类,但这里知道它所调用的代理对象的被代理者是UserDao类,所以用UserDao接收
UserDao ob = (UserDao) Proxy.newProxyInstance(ud.getClass()
getClassLoader(), ud.getClass().getInterfaces(), mh);
// 使用代理对象所代理的类的方法
ob.add();
ob.delete();
ob.find();
System.out.println("----------------");
// 这样的话,程序就会执行动态代理类的方法,按照那顺序来。
// 如果有别的类,如Student/Teachar类,也可以这样做:
StudentDao sd = new StudentDaoImpl();
// 对sd对象做个代理对象
MyInvocationHandler mh1 = new MyInvocationHandler(sd);
// 创建动态代理对象
StudentDao sd1 = (StudentDao) Proxy.newProxyInstance(sd.getClass()
.getClassLoader(), sd.getClass().getInterfaces(), mh1);
//调用方法
sd1.login();
sd1.regist();
}}
热点新闻