博客
关于我
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 - 4种基本索引、聚簇索引和非聚索引、索引失效情况、SQL 优化
查看>>
MySQL - ERROR 1406
查看>>
mysql - 视图
查看>>
MySQL - 解读MySQL事务与锁机制
查看>>
MTTR、MTBF、MTTF的大白话理解
查看>>
mt_rand
查看>>
mysql -存储过程
查看>>
mysql /*! 50100 ... */ 条件编译
查看>>
mudbox卸载/完美解决安装失败/如何彻底卸载清除干净mudbox各种残留注册表和文件的方法...
查看>>
mysql 1264_关于mysql 出现 1264 Out of range value for column 错误的解决办法
查看>>
mysql 1593_Linux高可用(HA)之MySQL主从复制中出现1593错误码的低级错误
查看>>
mysql 5.6 修改端口_mysql5.6.24怎么修改端口号
查看>>
MySQL 8.0 恢复孤立文件每表ibd文件
查看>>
MySQL 8.0开始Group by不再排序
查看>>
mysql ansi nulls_SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON 什么意思
查看>>
multi swiper bug solution
查看>>
MySQL Binlog 日志监听与 Spring 集成实战
查看>>
MySQL binlog三种模式
查看>>
multi-angle cosine and sines
查看>>
Mysql Can't connect to MySQL server
查看>>