Java--代理

代理:

  • 代理是什么?

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

静态代理举例

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);
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值