小言_互联网的博客

Java动态代理

551人阅读  评论(0)

1 动态代理

动态代理和静态代理角色一样
动态代理的代理类是动态生成的,不是我们直接写好的!
动态代理分为两大类:基于接口的动态代理,基于类的动态代理
基于接口—JDK动态代理
基于类:cglib
java字节码实现:JAVAssist

需要了解两个类:Proxy 代理,InvocationHandler 调用处理程序
动态代理的好处:

  1. 可以使真实角色的操作更加纯粹!不用去关注一些公共的业务
  2. 公共交给代理角色!实现了业务的分工!
  3. 公共业务发生扩展的时候,方便集中管理!
  4. 一个动态代理类代理的是一个接口,一般就是对应的一类业务
  5. 一个动态代理类可以代理多个类,只要是实现了同一个接口即可
    例子:继续以租房为例
    具体代码如下:
    租房
package com.jialidun.gof.demo02;

//租房
public interface Rent {
   

    public void rent();
}

房东,真实的角色

package com.jialidun.gof.demo02;

//房东
public class Host implements Rent {
   
    @Override
    public void rent() {
   
        System.out.println("房东要出租房子!");
    }
}

代理的角色
```java
package com.jialidun.gof.demo02;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//等我们会用这个类,自动生成代理类!
public class ProxyInvocationHandler implements InvocationHandler {
   

    //被处理的接口
    private Rent rent;

    public void setRent(Rent rent){
   
        this.rent = rent;
    }

    //生成得到代理类
    public Object getProxy(){
   
        //第一个参数加载到类在哪个位置
        //第二个参数表示代理的接口是哪一个
        //第三个参数是自己InvocationHandler
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);
    }


    //处理代理实例,并返回结果
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
   
        //动态代理的本质就是反射机制实现!
        seeHouse();
        Object result = method.invoke(rent, args);
        fee();
        return result;
    }

    public void seeHouse(){
   
        System.out.println("中介带看房子");
    }
    public void fee(){
   
        System.out.println("收中介费");
    }
}

我(要租房)

package com.jialidun.gof.demo02;

import com.jialidun.gof.agency.Proxy;

public class Client {
   
    public static void main(String[] args) {
   
        //真实角色
        Host host = new Host();

        //代理角色:没有手动创建
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        //通过调用程序处理角色来处理我们要调用的接口对象!
        pih.setRent(host);
        Rent proxy = (Rent) pih.getProxy();//这里的proxy就是动态生成的,我们并没有写~
        proxy.rent();


    }
}

改造成通用代码如下:

package com.jialidun.gof.demo03;

import com.jialidun.gof.demo02.Rent;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//等我们会用这个类,自动生成代理类!
public class ProxyInvocationHandler implements InvocationHandler {
   

    //被处理的接口
    private Object target;

    public void setTarget(Object target) {
   
        this.target = target;
    }

    //生成得到代理类
    public Object getProxy(){
   
        //第一个参数加载到类在哪个位置
        //第二个参数表示代理的接口是哪一个
        //第三个参数是自己InvocationHandler
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }


    //处理代理实例,并返回结果
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
   
        //动态代理的本质就是反射机制实现!

        log(method.getName());
        Object result = method.invoke(target, args);

        return result;
    }

    public void log(String msg){
   
        System.out.println("执行了"+msg+"方法");
    }
}

package com.jialidun.gof.demo03;

import com.jialidun.gof.demo.UserService;
import com.jialidun.gof.demo.UserServiceImpl;

/**
 * 动态代理:
 * Proxy类:生成动态代理类的实例的
 * InvocationHandler接口:处理代理实例,并返回结果的
 */
public class Client {
   
    public static void main(String[] args) {
   
        //真实角色
        UserServiceImpl userService = new UserServiceImpl();

        //代理角色,不存在
        ProxyInvocationHandler pih = new ProxyInvocationHandler();

        pih.setTarget(userService);//设置要代理的对象
        //动态生成代理类
        UserService proxy = (UserService) pih.getProxy();
        proxy.add();

    }
}


转载:https://blog.csdn.net/m0_51067047/article/details/117574989
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场