当前位置: 首页 > wzjs >正文

电子商务网站建设花费网站商城建设

电子商务网站建设花费,网站商城建设,开源的wordpress,成都企业展厅设计公司动态代理 文章目录 动态代理先来看一个示例定义接口实现接口创建动态代理类测试动态代理输出结果关键点解析 CGLIB 动态代理定义目标类(无需实现接口)创建 CGLIB 动态代理测试代码 JDK 动态代理 vs CGLIB 动态代理为什么需要使用代理对象?动态…

动态代理

文章目录

  • 动态代理
    • 先来看一个示例
      • 定义接口
      • 实现接口
      • 创建动态代理类
      • 测试动态代理
      • 输出结果
      • 关键点解析
    • CGLIB 动态代理
      • 定义目标类(无需实现接口)
      • 创建 CGLIB 动态代理
      • 测试代码
    • JDK 动态代理 vs CGLIB 动态代理
    • 为什么需要使用代理对象?
    • 动态代理适合的场景
    • 动态代理的优势
    • 什么时候不适合使用动态代理?
    • Spring 中动态代理的主要应用场景包括:
      • AOP(面向切面编程)
      • 事务管理
    • Spring 中动态代理的主要应用场景包括:
      • AOP(面向切面编程)
      • 事务管理

先来看一个示例

定义接口

// 定义一个业务接口
public interface UserService {void addUser(String name);void deleteUser(String name);
}

实现接口

// 实现接口的业务逻辑
public class UserServiceImpl implements UserService {@Overridepublic void addUser(String name) {System.out.println("添加用户: " + name);}@Overridepublic void deleteUser(String name) {System.out.println("删除用户: " + name);}
}

创建动态代理类

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;// 动态代理处理器
public class UserServiceProxyHandler implements InvocationHandler {private Object target; // 被代理的目标对象public UserServiceProxyHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 方法调用前增强逻辑System.out.println("代理前: 准备执行方法 " + method.getName());// 执行目标方法Object result = method.invoke(target, args);// 方法调用后增强逻辑System.out.println("代理后: 方法 " + method.getName() + " 执行完成");return result;}// 获取代理对象public Object getProxy() {return Proxy.newProxyInstance(target.getClass().getClassLoader(),         // 类加载器target.getClass().getInterfaces(),          // 目标对象实现的接口this                                       // 当前InvocationHandler实例);}
}

测试动态代理

public class DynamicProxyTest {public static void main(String[] args) {// 创建目标对象UserService userService = new UserServiceImpl();// 创建代理处理器并获取代理对象UserService proxyService = (UserService) new UserServiceProxyHandler(userService).getProxy();// 调用代理对象的方法proxyService.addUser("Alice");proxyService.deleteUser("Bob");}
}

输出结果

代理前: 准备执行方法 addUser
添加用户: Alice
代理后: 方法 addUser 执行完成
代理前: 准备执行方法 deleteUser
删除用户: Bob
代理后: 方法 deleteUser 执行完成

关键点解析

1.InvocationHandler 接口

  • proxy: 代理对象本身(通常不直接使用)
  • method: 被调用的目标方法
  • args: 方法参数

2.Proxy.newProxyInstance 方法

  • ClassLoader: 目标对象的类加载器
  • Class<?>[]: 目标对象实现的接口列表
  • InvocationHandler: 处理代理逻辑的处理器

3.适用场景

  • JDK 动态代理要求目标对象必须实现接口。如果目标对象没有实现接口,可以使用 CGLIB 动态代理。

4.扩展性

  • 可以在 invoke 方法中加入更多功能,如日志记录、性能监控、事务管理等。

CGLIB 动态代理

CGLIB 动态代理不要求目标对象实现接口,代理通过字节码生成子类的方式实现。

<dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.3.0</version>
</dependency>

定义目标类(无需实现接口)

public class UserService {public void addUser(String name) {System.out.println("添加用户: " + name);}public void deleteUser(String name) {System.out.println("删除用户: " + name);}
}

创建 CGLIB 动态代理

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;public class CglibProxyHandler implements MethodInterceptor {private Object target; // 被代理的目标对象public CglibProxyHandler(Object target) {this.target = target;}public Object getProxy() {Enhancer enhancer = new Enhancer();enhancer.setSuperclass(target.getClass()); // 设置父类为目标类enhancer.setCallback(this);               // 设置回调return enhancer.create();                 // 创建代理对象}@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println("CGLIB代理前: 准备执行方法 " + method.getName());Object result = method.invoke(target, args); // 执行目标方法System.out.println("CGLIB代理后: 方法 " + method.getName() + " 执行完成");return result;}
}

测试代码

public class CglibProxyTest {public static void main(String[] args) {UserService userService = new UserService();UserService proxyService = (UserService) new CglibProxyHandler(userService).getProxy();proxyService.addUser("Alice");proxyService.deleteUser("Bob");}
}

JDK 动态代理 vs CGLIB 动态代理

特性JDKL动态代理CGLB动态代理
实现方式基于接口基于继承(生成子类)
目标对象要求必须实现接口不需要实现接口
性能接口调用效率较高子类生成效率较低,但运行时性能接近
适用场景目标对象有接口目标对象无接口或需要代理类本身的方法
局限性无法代理类本身的非接口方法无法代理 final 类或 final 方法

为什么需要使用代理对象?

即使你已经通过 new 创建了具体的对象,直接使用它也能完成业务逻辑,但这种方式存在以下局限性:

1. 代码侵入性强

如果你希望在方法调用前后添加一些通用逻辑(如日志记录、性能监控、事务管理等),直接修改原始类的代码会破坏单一职责原则,并且会导致代码冗余。

2.功能扩展困难

假设你需要为某些方法添加权限校验或缓存支持,直接修改原始类会让代码变得复杂且容易出错。而代理可以在不修改原始类的情况下,动态地添加这些功能。

3. 解耦与复用

通过代理模式,可以将核心业务逻辑与非核心逻辑(如日志、事务)分离,提升代码的可读性和复用性。

动态代理适合的场景

动态代理的主要目的是在运行时动态地为目标对象添加额外的行为,而不改变其原有代码。以下是动态代理的典型应用场景:

1. 日志记录

在方法调用前后记录日志,便于调试和审计。

System.out.println("代理前: 准备执行方法 " + method.getName());
Object result = method.invoke(target, args);
System.out.println("代理后: 方法 " + method.getName() + " 执行完成");

2.性能监控

统计方法的执行时间,用于性能优化。

long startTime = System.currentTimeMillis();
Object result = method.invoke(target, args);
long endTime = System.currentTimeMillis();
System.out.println("方法执行耗时: " + (endTime - startTime) + "ms");

3. 事务管理

在方法调用前后开启和提交事务,确保数据一致性。

transactionManager.beginTransaction();
try {Object result = method.invoke(target, args);transactionManager.commit();return result;
} catch (Exception e) {transactionManager.rollback();throw e;
}

4. 权限校验

在方法调用前检查用户是否有权限执行该操作。

if (!securityManager.hasPermission(user, method)) {throw new SecurityException("无权访问");
}
return method.invoke(target, args);

5. 缓存支持

在方法调用前检查缓存中是否存在结果,避免重复计算。

String cacheKey = generateCacheKey(method, args);
if (cache.contains(cacheKey)) {return cache.get(cacheKey);
}
Object result = method.invoke(target, args);
cache.put(cacheKey, result);
return result;

6. 远程调用(RPC)

在分布式系统中,动态代理可以隐藏远程调用的细节,让开发者像调用本地方法一样调用远程服务。

// 动态代理实现 RPC 调用
Object result = rpcClient.invokeRemoteService(target, method, args);

动态代理的优势

  1. 透明性:动态代理对调用者是透明的,调用者无需关心代理的存在,只需像操作普通对象一样调用方法。
  2. 灵活性:代理逻辑可以在运行时动态生成,适用于多种场景(如日志、事务、权限等),而无需修改原始类。
  3. 解耦:将核心业务逻辑与非核心逻辑分离,符合单一职责原则和开闭原则。

什么时候不适合使用动态代理?

尽管动态代理非常强大,但它也有一些局限性,以下场景可能不适合使用动态代理:

1. 性能敏感场景

动态代理会引入一定的性能开销(尤其是 CGLIB),对于高频调用的场景可能需要权衡。

2. 简单任务

如果只是简单的功能调用,没有额外的需求(如日志、事务等),直接使用原始对象即可。

3. 静态需求

如果增强逻辑是固定的,且不需要动态生成,可以通过继承或装饰器模式实现。

Spring 中动态代理的主要应用场景包括:

AOP(面向切面编程)

  • 用于增强方法调用(如日志记录、性能监控、权限校验等)。
  • 示例:通过 @Aspect 注解定义切面逻辑。

事务管理

  • 用于声明式事务控制。
  • 示例:通过 @Transactional 注解实现事务管理。

定的性能开销(尤其是 CGLIB),对于高频调用的场景可能需要权衡。

2. 简单任务

如果只是简单的功能调用,没有额外的需求(如日志、事务等),直接使用原始对象即可。

3. 静态需求

如果增强逻辑是固定的,且不需要动态生成,可以通过继承或装饰器模式实现。

Spring 中动态代理的主要应用场景包括:

AOP(面向切面编程)

  • 用于增强方法调用(如日志记录、性能监控、权限校验等)。
  • 示例:通过 @Aspect 注解定义切面逻辑。

事务管理

  • 用于声明式事务控制。
  • 示例:通过 @Transactional 注解实现事务管理。
http://www.dtcms.com/wzjs/802585.html

相关文章:

  • 企业网站经典案例人才市场招聘网站
  • 网站维护 案例环球设计网
  • 视频素材网站推荐建筑设计网上接单
  • 电子商务网站建设的一般曲靖模板网站建设
  • 网站设计实施陕西咸阳建设银行网站
  • 珠海网站建设公电商网站的建设背景
  • 装修公司谁做网站wordpress网站生成app应用
  • 设计师常用的图片网站wordpress主题二级菜单栏
  • 徐州沛县网站建设东莞工厂
  • 免费建设手机网站小型IT网站开发公司
  • 网站建设pc端青岛做教育的网站建设
  • 深圳网站建设收费标准网站备案费用多少
  • 大连鼎信网站建设江西网站开发企业
  • 免费的app软件下载网站展览馆网站建设方案书
  • 做旅游游客产品的网站公司网站维护和更新属于哪个部门
  • 什么是可信网站手机自己免费制作app软件
  • 浙江龙元建设集团 网站湖南网站服务
  • 丰城住房和城乡建设部网站潍坊360做网站怎么样
  • python整合网站开发技术网站制作什么品牌好
  • 做蛋糕比较火的网站网站域名后缀的意思
  • 装修素材网站有哪些c 做交易网站
  • 苏州开设网站公司在什么地方搜索引擎广告形式有
  • 移动云网站建设中国各大网站排名
  • 网站栏目及内容山西省住房城乡建设厅网站首页
  • 网站域名备案需要什么c2c网站建设价格
  • 浙江中立建设有限公司网站佛山营销网站设计
  • 淮安网站建设费用父亲节ppt模板免费下载
  • 手机查看别人网站代码吗简洁的网页模板
  • django网站开发视频教程房山广州网站建设
  • 南山网站设计多少钱公司网站怎么自己做