JavaSE-Dynamic Agent

1.1 Dynamic proxy

  • The role of dynamic proxy is the same as that of static proxy. The proxy class of dynamic proxy is dynamically generated. The proxy class of static proxy is written in advance.
  • Dynamic agents are divided into two categories: one is dynamic agents based on interfaces, and the other is dynamic agents based on classes.
    • Interface-based dynamic proxy ---- JDK dynamic proxy.
    • Class-based dynamic proxy-cglib.
    • Nowadays, javasist is used more frequently to generate dynamic agents. Baidu about javasist.

The dynamic proxy of JDK needs to understand two classes: InvocationHandler and Proxy

InvocationHandler【Invocation handler】

Object invoke(Object proxy, 方法 method, Object[] args)//参数
//proxy - 调用该方法的代理实例
//method -所述方法对应于调用代理实例上的接口方法的实例。 方法对象的声明类将是该方法声明的接
口,它可以是代理类继承该方法的代理接口的超级接口。
//args -包含的方法调用传递代理实例的参数值的对象的阵列,或null如果接口方法没有参数。 原始
类型的参数包含在适当的原始包装器类的实例中,例如java.lang.Integer或java.lang.Boolean
。

Pxoxy【Proxy】

//生成代理类
public Object getProxy(){
    
    
  return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                 rent.getClass().getInterfaces(),this);
}

1.2 Code example

Rent interface (abstract role)

package cn.guardwhy.domain;
// 抽象角色:租房
public interface Rent {
    
    
    public void rent();
}

Landlord

package cn.guardwhy.domain;
// 真实角色: 房东,要出租房子
public class Landlord implements Rent {
    
    
    @Override
    public void rent() {
    
    
        System.out.println("房屋出租!!!");
    }
}

ProxyInvocationHandler is the proxy role

package cn.guardwhy.proxy;

import cn.guardwhy.domain.Rent;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 该类自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {
    
    
    // 1.被代理的接口
    private Rent rent;

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

    // 2.生成得到代理类

    public Object getProxy(){
    
    
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                rent.getClass().getInterfaces(), this);
    }

    // 3.处理代理实例,并且返回结果
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
        seeHouse();
        // 动态代理的本质。就是使用反射机制实现
        Object result = method.invoke(rent, args);
        fare();
        return result;
    }
    // 4.方法
    public void seeHouse(){
    
    
        System.out.println("带房客看房...");
    }
    // 收中介费
    public void fare(){
    
    
        System.out.println("收中介费");
    }
}

Client (tenant)

package cn.guardwhy.client;

import cn.guardwhy.domain.Landlord;
import cn.guardwhy.domain.Rent;
import cn.guardwhy.proxy.ProxyInvocationHandler;

public class Client {
    
    
    public static void main(String[] args) {
    
    
        // 1.真实角色
        Landlord landlord = new Landlord();
        // 2.代理角色
        ProxyInvocationHandler pith = new ProxyInvocationHandler();
        // 3.通过调用程序处理角色来处理要调用的接口对象
        pith.setRent(landlord);
        Rent proxy = (Rent) pith.getProxy();
        // 4.调用接口
        proxy.rent();
    }
}

The results

to sum up

A dynamic agent generally acts for a certain type of business, and a dynamic agent can act for multiple classes, and the agent is an interface

1.3 Deepen dynamic agency

UserService

package cn.guardwhy.domain;
// 抽象角色,增删改查业务
public interface UserService {
    
    
    void add();
    void delete();
    void update();
    void query();
}

UserServiceImpl

package cn.guardwhy.domain;

// 真实对象,完成增删改查的操作
public class UserServiceImpl implements UserService {
    
    
    @Override
    public void add() {
    
    
        System.out.println("增加了一个用户");
    }

    @Override
    public void delete() {
    
    
        System.out.println("删除了一个用户");
    }

    @Override
    public void update() {
    
    
        System.out.println("更新了一个用户");
    }

    @Override
    public void query() {
    
    
        System.out.println("查询一个用户");
    }
}

Write a generic dynamic proxy implementation class! All proxy objects are set to Object.

package cn.guardwhy.proxy;

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

public class ProxyInvocationHandler2 implements InvocationHandler {
    
    
    // 1.被代理的接口
    private Object target;
    // 2.set注入
    public void setTarget(Object target) {
    
    
        this.target = target;
    }

    // 3.生成得到代理类
    public Object getProxy(){
    
    
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }

    // 4.处理代理实例,并且返回结果
    @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 + "方法" );
    }
}

Client (tenant)

package cn.guardwhy.client;

import cn.guardwhy.domain.UserService;
import cn.guardwhy.domain.UserServiceImpl;
import cn.guardwhy.proxy.ProxyInvocationHandler2;

public class Client2 {
    
    
    public static void main(String[] args) {
    
    
        //1.真实角色
        UserServiceImpl userService = new UserServiceImpl();
        //2.代理对象的调用处理程序
        ProxyInvocationHandler2 pith = new ProxyInvocationHandler2();
        //3.设置要代理的对象
        pith.setTarget(userService);
        // 动态生成代理类
        UserService proxy = (UserService) pith.getProxy();
        //4.调用方法
        proxy.add();
    }
}

The results

1.4 Benefits of dynamic proxy

Some static agents have it, and static agents do not have it!

  • Can make our real role more pure. No longer pay attention to some public things.
  • The public business is completed by the agent. The division of labor is realized,
  • When public business expands, it becomes more centralized and convenient.
  • Dynamic agent, generally agent a certain type of business, a dynamic agent can agent multiple types, the agent is an interface.

Guess you like

Origin blog.csdn.net/hxy1625309592/article/details/115080607