clearwind

clearwind

首页
分类
登录 →
clearwind

clearwind

首页 分类
登录
  1. 首页
  2. 🎯Java
  3. 代理模式

代理模式

0
  • 🎯Java
  • 发布于 2024-07-05
  • 55 次阅读
clearwind
clearwind

# 一、代理模式

## 定义

由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。

代理模式的主要优点有:

- 代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用;

- 代理对象可以扩展目标对象的功能;

- 代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度,增加了程序的可扩展性。

## 代理模式的结构与实现

### 模式的结构

- 抽象主题(Subject)类:通过接口或抽象类声明真实主题和代理对象实现的业务方法。

- 真实主题(Real Subject)类:实现了抽象主题中的具体业务,是最终要引用的对象。

- 代理(Proxy)类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。

![image.png](http://qnimg.cvccy.com/xhf/%7Byear%7D/%7Bmonth%7D/%7Bfilename%7D%7B.suffix%7D/image_1602331881515.png!lg)

### 模式的实现

```java

// 抽象接口

public interface Subject {

void optation();

}

// 真实实现

public class RealSubject implements Subject {

@Override

public void optation() {

System.out.println("Progremming RealSubjecg [doSometing].");

}

}

// 代理类

public class MyProxy {

private RealSubject subject = new RealSubject();

public void optaion(){

System.out.println("Preprocessor before targer method running.");

subject.optation();

System.out.println("Postprocessor after target method running.");

}

}

// 测试类

public class Client {

public static void main(String[] args) {

MyProxy proxy = new MyProxy();

proxy.optaion();

}

}

```

# 二、Jdk Dynamic Proxy

JDK的动态代理的对象必须实现一个或多个接口。

## 模式的实现

```java

// 代理类

public class JdkDynamicProxy implements InvocationHandler {

private Object target;

public JdkDynamicProxy(Object target) {

this.target = target;

}

public <T> T getProxy(){

return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);

}

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

System.out.println("Preprocessor by JDKProxy before targer method running.");

method.invoke(target,args);

System.out.println("Postprocessor by JDKProxy after target method running.");

return null;

}

}

//测试类

public class Client {

public static void main(String[] args) {

Subject subject = new JdkDynamicProxy(new RealSubject()).getProxy();

subject.optation();

}

}

// 执行结果

Preprocessor by JDKProxy before targer method running.

Progremming RealSubjecg [doSometing].

Postprocessor by JDKProxy after target method running.

```

# 三、Cglib Dynamic Proxy

Cglib代理,也叫做子类代理,是一个强大的高性能的代码生成包,它可以在运行期在内存中构建一个子类对象从而实现扩展Java类与实现Java接口。CGLIB包的底层是通过使用一个`字节码处理框架ASM`,来转换字节码并生成新的类。ASM具体的功能实现涉及到JVM内部结构包括class文件的格式和指令集。

## 特点

- 需要引入cglib jar文件,spring的核心包中已经包括了cglib功能,所以直接引入spring-core-3.2.5.jar也可。

- 代理的类不能为final, 否则报错。

- 目标对象的方法如果为final/static,不会被拦截,即不会执行目标对象额外的业务方法。

## 引入依赖

```xml

<dependency>

<groupId>cglib</groupId>

<artifactId>cglib</artifactId>

<version>3.3.0</version>

</dependency>

```

## 模式实现

```java

// 目标类

public class Subject {

public void insert(){

System.out.println("insert");

select();

}

public void select(){

System.out.println("select");

}

public void delete(){

System.out.println("delete");

}

public void updata(){

System.out.println("updata");

}

}

// 代理类

public class CglibDynamicProxy implements MethodInterceptor {

private static Object target;

public CglibDynamicProxy(Object target) {

this.target = target;

}

public <T> T getProxy(){

Enhancer enhancer = new Enhancer();

enhancer.setSuperclass(target.getClass());

enhancer.setCallback(this);

return (T) enhancer.create();

}

@Override

public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

System.out.print("Before ");

methodProxy.invokeSuper(o,objects);

return null;

}

}

//测试类

public class Client {

public static void main(String[] args) {

CglibDynamicProxy cglibDynamicProxy = new CglibDynamicProxy(new Subject());

Subject subject = cglibDynamicProxy.getProxy();

subject.insert();

}

}

// 执行结构

Before insert

Before select

```

# 四、JDk与Cglib代理

## 生成的代理文件

1、jdk代理(InvocationHandler)

Jdk代理会根据接口生成动态代理字节码文件,生成的代理类实现目标类(Subject)[$oroxy.class implement Subject]。执行目标方法的方式是通过反射的方法直接调用原Bean的方法。

2、cglib代理(MethodInterceptor)

Cglib代理是通过ASM生成继承被代理类的class(多个),会重写被代理类的方法。执行目标方法的方式是子类重写的方法。

## 代理的重复性

代理的重复增强是在增强的类中方法A调用方法B,是否会重复执行代理增强的功能。

- Jdk动态代理不会重复增强[通过反射调用原方法]

- cglib动态代理会重复增强[执行代理实现的子类]

相关文章

订单引擎 2024-09-17 20:31

订单状态流转是交易系统的最为核心的功能,复杂的订单系统会存在状态多、链路长、逻辑复杂的特点,针对不同的商品、业务、发货方式还存在多场景、多类型、多业务维度等业务特性。在保证订单状态流转稳定性的前提下、可扩展性和可维护性由是需要重点关注和解决的问题。 以公司目前的订单系统为例,订单状态有待支付、支付成

图解RocketMQ架构

图解RocketMQ架构 2024-08-22 11:41

RocketMQ 总共可以分成四个模块 NameServer:提供服务发现和路由功能,管理各种元数据信息。 Broker:消息存储和路由分发节点,负责存储消息和将消息路由给消费者。 Producer:消息生产者,负责产生并发送消息到指定的 T

Redis Cluster 2024-07-05 00:23

redis集群是一个由多个主从节点群组成的分布式服务器群,它具有复制、高可用和分片特性,不需要sentinel哨兵也能完成节点移除和故障转移的功能。需要将每个节点设置成集群模式,这种集群模式没有中心节点,可水平扩展。 redis下载安装 参考<Redis使用> Redis集群搭建 redis集群需要

代理模式 2024-07-05 00:21

# 一、代理模式 ## 定义 由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。 代理模式的主要优点有: - 代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用; - 代理对象可以扩展目标

适配器(端口)-调用外部接口 2024-07-01 11:12

面向接口编程思想、多态思想-解耦代码逻辑 在领域驱动设计(DDD)的上下文中,适配器(Adapter)模式扮演着至关重要的角色。适配器模式允许将不兼容的接口转换为另一个预期的接口,从而使原本由于接口不兼容而不能一起工作的类可以协同工作。在DDD中,适配器通常与端口(Port)概念结合使用,形成"端口

单线程的Redis 为何如此快速?

单线程的Redis 为何如此快速? 2024-06-14 21:46

基于RAM IO多路复用&单线程读写 高效的数据结构

目录
  • clearwind
  • 微信小程序

导航菜单

  • 首页
  • 分类
Copyright © 2024 your company All Rights Reserved. Powered by clearwind.
皖ICP备19023482号