铁匠 铁匠
首页
收藏
java
架构之路
常用算法
  • Java
  • nginx
  • 系统运维
  • 系统安全
  • mysql
  • redis
参考文档
关于
链接
  • 分类
  • 标签
  • 归档

专注、不予评判地关注当下
首页
收藏
java
架构之路
常用算法
  • Java
  • nginx
  • 系统运维
  • 系统安全
  • mysql
  • redis
参考文档
关于
链接
  • 分类
  • 标签
  • 归档
  • 概览

  • 设计模式

    • 软件设计原则
    • 创建型

    • 结构型

      • 装饰器模式
      • 委派模式
      • 代理模式
        • 静态代理
        • 动态代理
          • JDK 实现
          • cglib 实现
          • bytebuddy 实现
    • 行为型

  • 高可用

  • 性能优化

  • 分布式

  • 网关

  • 流量治理

  • 数据治理

  • 云原生

  • 网络安全

  • 架构
  • 设计模式
  • 结构型
fengjx
2023-01-03
目录

代理模式

代理模式和装饰器模式一样,都是在不修改原始类的情况下,增强功能。代理模式的侧重点在于扩展功能,装饰器的侧重点在于多个功能组合使用。

通过不同的代理模式,实现这样一个需求:通过代理类对 api 接口做鉴权判断,并能应用到多个接口上。

# 静态代理

public interface Controller {

    void request(String param);

}

public class UserController implements Controller {

    @Override
    public void request(String param) {
        System.out.println("request user api: " + param);
    }
}

public class AuthorityControllerProxy implements Controller {

    private final Controller target;

    public AuthorityControllerProxy(final Controller target) {
        this.target = target;
    }

    @Override
    public void request(final String param) {
        if (!"admin".equals(param)) {
            System.out.println("401");
            return;
        }
        target.request(param);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

测试类

public class WebApp {

    public static void main(String[] args) {
        Controller controller = new AuthorityControllerProxy(new UserController());
        controller.request("user");
        controller.request("admin");
    }
}
1
2
3
4
5
6
7
8

# 动态代理

# JDK 实现

public interface Controller {

    void request(String param);

}

public class UserController implements Controller {

    @Override
    public void request(String param) {
        System.out.println("request user api: " + param);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
// 创建代理对象工具类
public class JdkProxyKit {

    public static <T> T newProxyInstance(Object obj, InvocationHandler handler) {
        final ClassLoader classLoader = obj.getClass().getClassLoader();
        final Class<?>[] interfaces = obj.getClass().getInterfaces();
        final Object instance = Proxy.newProxyInstance(classLoader, interfaces, handler);
        return (T) instance;
    }
}

// 扩展代理类功能
public class AuthorityControllerJdkProxy implements InvocationHandler {

    private final Controller target;

    public AuthorityControllerJdkProxy(final Controller target) {
        this.target = target;
    }

    @Override
    public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
        if (args == null || args.length < 1) {
            System.out.println("401");
            return null;
        }
        String param = (String) args[0];
        if (!"admin".equals(param)) {
            System.out.println("401");
            return null;
        }
        return method.invoke(target, args);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

测试类

public class JdkProxyApp {

    public static void main(String[] args) {
        Controller controller = new UserController();
        final AuthorityControllerJdkProxy handler = new AuthorityControllerJdkProxy(controller);
        final Controller proxyController = JdkProxyKit.newProxyInstance(controller, handler);
        System.out.println(proxyController.getClass().getName());
        proxyController.request("user");
        proxyController.request("admin");
    }
}
1
2
3
4
5
6
7
8
9
10
11

# cglib 实现

public class AdminController {

    public void request(String param) {
        System.out.println("request admin api: " + param);
    }
}

public class AuthorityControllerCglibProxy implements MethodInterceptor {


    private final Object target;

    public AuthorityControllerCglibProxy(final Object target) {
        this.target = target;
    }

    @Override
    public Object intercept(final Object obj, final Method method, final Object[] args, final MethodProxy proxy) throws Throwable {
        if (args == null || args.length < 1) {
            System.out.println("401");
            return null;
        }
        String param = (String) args[0];
        if (!"admin".equals(param)) {
            System.out.println("401");
            return null;
        }
        return method.invoke(target, args);
    }
}

public class CglibProxyKit {

    @SuppressWarnings("unchecked")
    public static <T> T newProxyInstance(T target, MethodInterceptor interceptor) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(interceptor);
        return (T) enhancer.create();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

测试类

public class CglibProxyApp {

    public static void main(String[] args) {
        AdminController controller = new AdminController();
        final AuthorityControllerCglibProxy proxy = new AuthorityControllerCglibProxy(controller);
        final AdminController proxyController = CglibProxyKit.newProxyInstance(controller, proxy);
        proxyController.request("user");
        proxyController.request("admin");
    }
}
1
2
3
4
5
6
7
8
9
10

其他 cglib 用法:https://github.com/cglib/cglib (opens new window)

# bytebuddy 实现

public class AdminController {

    public void request(String param) {
        System.out.println("request admin api: " + param);
    }
}

public class AuthorityControllerByteBuddyProxy {

    private final AdminController target;

    public AuthorityControllerByteBuddyProxy(final AdminController target) {
        this.target = target;
    }

    public void request(String param) {
        if (!"admin".equals(param)) {
            System.out.println("401");
            return;
        }
        target.request(param);
    }
}

public class ByteBuddyProxyKit {

    @SuppressWarnings({"resource", "unchecked"})
    public static <T> T newProxyInstance(Class<T> targetClass, String methodName, Object delegate)
            throws InstantiationException, IllegalAccessException {
        Class<?> dynamicType = new ByteBuddy()
                .subclass(targetClass)
                .method(ElementMatchers.named(methodName))
                .intercept(MethodDelegation.to(delegate))
                .make()
                .load(targetClass.getClassLoader())
                .getLoaded();
        return (T) dynamicType.newInstance();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

测试类

public class ByteBuddyProxyApp {

    public static void main(String[] args) throws InstantiationException, IllegalAccessException {
        AdminController controller = new AdminController();
        AuthorityControllerByteBuddyProxy proxy = new AuthorityControllerByteBuddyProxy(controller);
        final AdminController proxyController = ByteBuddyProxyKit.newProxyInstance(AdminController.class, "request", proxy);
        proxyController.request("user");
        proxyController.request("admin");
    }
}
1
2
3
4
5
6
7
8
9
10

其他 bytebuddy 用法:https://github.com/raphw/byte-buddy (opens new window)

#代理模式
委派模式
观察者模式

← 委派模式 观察者模式→

最近更新
01
策略模式
01-09
02
模板方法
01-06
03
观察者模式
01-06
更多文章>
Theme by Vdoing | Copyright © 2016-2023 铁匠 | 粤ICP备15021633号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式