java 27 - 10 反射之 动态代理的代码实现
为什么要写动态代理类?
例子:
如果现在想做个登陆注册的功能。用户可以执行登陆、注册、添加、删除这些功能。
但是,有些功能是要有一定权限才可以执行的。
而现在已经有了个用户类的接口和该类的实现类了,但里面没有添加 “权限查询”和“日志记录”这两个功能。
这个时候我不可能去改动这两个类,而且,我以后遇到类似的情况,也不想重复改动。(不想原来的类做,让别的类帮它们做)
那么,我就可以写一个动态代理类和执行类
代码:
A:用户的接口类
1 /* 2 * 用户操作接口 3 */ 4 public interface UserDao { 5 public abstract void add(); 6 7 public abstract void delete(); 8 9 public abstract void update(); 10 11 public abstract void find(); 12 }
B:用户接口的实现类(模拟功能)
1 public class UserDaoImpl implements UserDao { 2 3 public void add() { 4 System.out.println("添加功能"); 5 } 6 7 public void delete() { 8 System.out.println("删除功能"); 9 } 10 11 public void update() { 12 System.out.println("修改功能"); 13 } 14 15 public void find() { 16 System.out.println("查找功能"); 17 } 18 19 }
C:动态代理类
/** * 这是对实现用户操作之前的权限检查的动态代理类 * * @author LZL * */ //注意:创建这个类要实现动态代理接口 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:执行类
1 public class Test { 2 3 public static void main(String[] args) { 4 5 // 创建UserDao的实现类对象 6 UserDao ud = new UserDaoImpl(); 7 8 // 我们要创建一个动态代理对象 9 // Proxy类中有一个方法可以创建动态代理对象 10 // public static Object newProxyInstance(ClassLoader loader,Class<?>[] 11 // interfaces,InvocationHandler h) 12 13 // 对ud对象做一个代理对象 14 MyInvocationHandler mh = new MyInvocationHandler(ud); 15 // 创建一个动态代理对象,本来这个方法返回的是Object类,但这里知道它所调用的代理对象的被代理者是UserDao类,所以用UserDao接收 16 UserDao ob = (UserDao) Proxy.newProxyInstance(ud.getClass() 17 .getClassLoader(), ud.getClass().getInterfaces(), mh); 18 // 使用代理对象所代理的类的方法 19 ob.add(); 20 ob.delete(); 21 ob.find(); 22 23 System.out.println("----------------"); 24 // 这样的话,程序就会执行动态代理类的方法,按照那顺序来。 25 // 如果有别的类,如Student/Teachar类,也可以这样做: 26 27 StudentDao sd = new StudentDaoImpl(); 28 // 对sd对象做个代理对象 29 MyInvocationHandler mh1 = new MyInvocationHandler(sd); 30 // 创建动态代理对象 31 StudentDao sd1 = (StudentDao) Proxy.newProxyInstance(sd.getClass() 32 .getClassLoader(), sd.getClass().getInterfaces(), mh1); 33 //调用方法 34 sd1.login(); 35 sd1.regist(); 36 37 } 38 }
何事都只需坚持..
难?
维熟尔。
LZL的自学历程...只需坚持