博客
关于我
Java--代理
阅读量:285 次
发布时间:2019-03-01

本文共 4423 字,大约阅读时间需要 14 分钟。

代理:

  • 代理是什么?

代理就是在不修改源代码的情况下,对该类的方法进行扩展(增强)。

静态代理举例

interface ClothFactory{       void productCloth();}//代理类class ProxyClothFactory implements ClothFactory{       private ClothFactory factory;    public ProxyClothFactory(ClothFactory factory) {           this.factory = factory;    }    @Override    public void productCloth() {           System.out.println("我是衣服代理类");        factory.productCloth();        System.out.println("代理工厂后续工作");    }}//被代理类class NickClothFactory implements ClothFactory{       @Override    public void productCloth() {           System.out.println("Nick工厂生产衣服");    }}public class StaticProxy {       public static void main(String[] args) {           //创建被代理类        NickClothFactory nickClothFactory=new NickClothFactory();        //创建代理类        ProxyClothFactory proxyClothFactory = new ProxyClothFactory(nickClothFactory);        proxyClothFactory.productCloth();    }}

动态代理

动态代理主要是通过Proxy创建接口代理对象,所以首要问题就是如何通过Proxy创建接口代理对象。

创建接口代理对象主要使用的方法是:

  • newProxyInstance(ClassLoad,Interfaces,InvocationHandler)

第一个参数:我们可以填写接口实现类的类加载器

第二个参数:实现类的实现接口
第三个参数:创建一个InvocationHandler接口的实现子类(增强方法在该子类里面)

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

这里通过一个demo学习:

OneDao:

public interface OneDao {       public int add(int a,int b);}

OneDaoImpl:

public class OneDaoImpl implements OneDao {           @Override    public int add(int a, int b) {           return a+b;    }}

我们的目的就是增强OneDaoImpl的add方法。

创建InvocationHandler 的实现子类:

class MyHandler implements InvocationHandler{       //传入被代理的实现类    private Object object;    public MyHandler(Object object){           this.object=object;    }        //增强方法逻辑    /**     *     * @param proxy :当前代理对象     * @param method:当前执行方法名称     * @param args  :执行方法参数     * @return     * @throws Throwable     */    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {           //方法前        System.out.println("方法前...."+method.getName());        //获得方法的第一个参数        System.out.println(args[0]);                //执行方法        Object res=method.invoke(object,args);                //方法后        System.out.println("方法后...."+method.getName());        return res;    }}

获得代理对象:

@Test    public void method(){                   OneDaoImpl oneDao=new OneDaoImpl();        OneDao dao  = (OneDao) Proxy.newProxyInstance(OneDaoImpl.class.getClassLoader(), OneDaoImpl.class.getInterfaces(), new MyHandler(oneDao));        int add = dao.add(1, 2);        System.out.println(add);    }

(以下内容为之前所写,表达的不清楚)

interface Human{       int getAge();    String getName();}//被代理类class GDPeople implements Human{       private int age;    private String name;    public GDPeople(int age, String name) {           this.age = age;        this.name = name;    }    @Override    public int getAge() {           return age;    }    @Override    public String getName() {           return name;    }}/**    要想实现动态代理,需要解决的问题:    1,如果根据加载到内存中的被代理类,动态创建一个代理类及其对象    2,当通过代理类的对象调用方法时,如何动态的去调用被代理类中的同名方法 */class ProxyFactory{       //调用此方法,返回一个代理类的对象。解决问题一    public static Object getProxyInstance(Object obj){   //obj:被代理类的对象        MyInvocationHandler handler=new MyInvocationHandler();        handler.bind(obj);        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),handler);    }}class MyInvocationHandler implements InvocationHandler {       private Object object;//需要使用被代理类的对象进行赋值    public void bind(Object object){           this.object=object;    }    //当我们通过代理类的对象,调用方法a时,就会自动调用如下的方法:invoke()    //当被代理类要执行的方法a功能就声明在invoke()中    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {           //method:即为代理类对象调用的方法,此方法也就作为了被代理类对象要调用的方法        System.out.println("代理之前");        //obj:被代理类的对象        Object invoke = method.invoke(object, args);        //上述方法的返回值就作为当前类中invoke()的返回值        System.out.println("代理之后");        return invoke;    }}public class ProxyTest {       public static void main(String[] args) {           GDPeople gdPeople=new GDPeople(15,"Tom");        Human proxyInstance = (Human) ProxyFactory.getProxyInstance(gdPeople);        //当通过代理类对象调用方法时,会自动的调用被代理类中同名的方法        int age = proxyInstance.getAge();        String name = proxyInstance.getName();        System.out.println("name:"+name+"-----age:"+age);    }}

转载地址:http://chca.baihongyu.com/

你可能感兴趣的文章
MySQL 查看有哪些表
查看>>
mysql 查看锁_阿里/美团/字节面试官必问的Mysql锁机制,你真的明白吗
查看>>
MySql 查询以逗号分隔的字符串的方法(正则)
查看>>
MySQL 查询优化:提速查询效率的13大秘籍(避免使用SELECT 、分页查询的优化、合理使用连接、子查询的优化)(上)
查看>>
mysql 查询数据库所有表的字段信息
查看>>
【Java基础】什么是面向对象?
查看>>
mysql 查询,正数降序排序,负数升序排序
查看>>
MySQL 树形结构 根据指定节点 获取其下属的所有子节点(包含路径上的枝干节点和叶子节点)...
查看>>
mysql 死锁 Deadlock found when trying to get lock; try restarting transaction
查看>>
mysql 死锁(先delete 后insert)日志分析
查看>>
MySQL 死锁了,怎么办?
查看>>
MySQL 深度分页性能急剧下降,该如何优化?
查看>>
MySQL 深度分页性能急剧下降,该如何优化?
查看>>
MySQL 添加列,修改列,删除列
查看>>
mysql 添加索引
查看>>
MySQL 添加索引,删除索引及其用法
查看>>
mysql 状态检查,备份,修复
查看>>
MySQL 用 limit 为什么会影响性能?
查看>>
MySQL 用 limit 为什么会影响性能?有什么优化方案?
查看>>
MySQL 用户权限管理:授权、撤销、密码更新和用户删除(图文解析)
查看>>