【JDK动态代理】

来源:互联网 发布:淘宝拍图动作 编辑:程序博客网 时间:2024/06/07 20:44

都是在学习的路上前进,别把自己比喻的太强大,也别太贬低自己的能力


最近在学习Spring框架,Spring框架的AOP技术底层也是采用的代理技术,代理的方式提供了两种


(1)基于JDK的动态代理 必须是面向接口的,只有实现了具体接口的类才能生成代理对象


(2)基于CGLIB动态代理 对于没有实现的接口类,也可以产生代理,产生这个类的子类的方式


今天我们就说说JDK的动态代理:这里废话不多说直接上代码


1>首先定义一个UserDao的接口

public interface UserDao {public void save();public void update();}
这个接口中提供两个方法,既save()方法和update()方法


2>定义一个接口的实现类UserDaoImpl

public class UserDaoImpl implements UserDao {@Overridepublic void save() {System.out.println("保存用户");}@Overridepublic void update() {System.out.println("修改用户");}}
实现接口中的方法,并做一些简单的输出

3>用传统的创建对象的方式来测试一下代码

@Testpublic void method1() {// 目标对象UserDao ud = new UserDaoImpl();ud.save();ud.update();}

这里我们可以看到在控制台打印了 保存用户和修改用户


重点来了!!!那么我们如何在不修改源代码的情况下去增加 save()方法和update()方法的功能呢,要知道程序修改的过程中如果动源代码,那将是一场灾难,JDK的动态代理很好的帮我们解决了这个问题


首先说明我们会用到Proxy,这是Java反射包中的不是lang包下的(java.lang.reflect.Proxy;)

上代码吗,我注释写的很全

/** * 使用JDK的方式来生成代理对象 *  * @author Google * */public class MyProxyUtils {// 注释1:因为内部类要用到UserDao所以此处要定义为final// 注释2:生成动态的UserDao的代理对象public static UserDao getProxy(final UserDao userDao) {// 1.使用Proxy类来生成代理对象// 解释: Proxy.newProxyInstance(ClassLoader loader,Class<?>[]// interfaces,nvocationHandler h); 三个参数/** * @1 ClassLoader loader 为接口类的classLoader(这里就是UserDao) *  * @2 Class<?>[] interfaces 为该类所实现的接口,采用反射方式获取 *  * @3 nvocationHandler h 为 InvocationHandler 是一个回调接口 */UserDao proxy = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(),new InvocationHandler() {// 只要代理对象的方法一执行 我的invoke方法就执行@Override/** * @1 proxy 表示当前生成的代理对象 一般不要用 这个对象,会无限循环导致内存溢出 *  * @2 method 反射方法 *  * @3 args 动态代理对象方法中的参数(这里就是UserDao) */public Object invoke(Object proxy, Method method,Object[] args) throws Throwable {// 解释:如果没有逻辑判断的话,save() update()方法将会正常执行// 这里想要在不修改源码的情况下 增加日志功能if (method.getName().equals("save")) {System.out.println("记录日志");} else {System.out.println("没有记录日志");}// 让dao类的save或者update方法正常的执行下去return method.invoke(userDao, args);}});// 返回我的代理对象return proxy;}}


这里我们在做一次代码的测试

@Testpublic void method1() {// 目标对象UserDao ud = new UserDaoImpl();ud.save();ud.update();System.out.println("..........");// 使用工具类去获取到代理对象// 代理对象UserDao proxy = MyProxyUtils.getProxy(ud);proxy.save();proxy.update();}

用分割线隔开输出可以看到结果如下

保存用户
修改用户
..........
记录日志
保存用户
没有记录日志
修改用户

是不是很简单...面试的时候可以说哦!!!



0 0
原创粉丝点击