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

网站原型图设计软件百度联盟是什么

网站原型图设计软件,百度联盟是什么,黄页名录网站开发,htmi 个人小网站 模板在 Spring 框架中,AOP(面向切面编程)是其核心特性之一,而实现 AOP 的关键在于代理机制。Spring 提供了两种主要的代理方式:JDK 动态代理和 CGLIB 代理。理解这两种代理方式的原理、优缺点及适用场景,对于深…

在 Spring 框架中,AOP(面向切面编程)是其核心特性之一,而实现 AOP 的关键在于代理机制。Spring 提供了两种主要的代理方式:JDK 动态代理和 CGLIB 代理。理解这两种代理方式的原理、优缺点及适用场景,对于深入掌握 Spring AOP 至关重要。本文将结合你的学习笔记,详细解析这两种代理机制,并通过代码示例和性能对比帮助你更好地理解和记忆。

一、JDK 动态代理:基于接口的代理实现

1. 核心原理

JDK 动态代理是 Java 原生提供的代理机制,其核心基于 Java 反射机制。它要求目标类必须实现至少一个接口,代理对象会实现相同的接口,从而在运行时动态拦截对目标方法的调用。

代理对象的生成过程主要涉及以下几个步骤:

  • 通过Proxy.getProxyClass()方法生成实现了目标接口的代理类字节码
  • 使用ClassLoader加载该字节码生成 Class 对象
  • 通过反射调用构造器创建代理实例

2. 代码实现示例

下面是一个使用 JDK 动态代理的简单示例:

// 定义业务接口
public interface UserService {void saveUser(String username);String getUserById(Long id);
}// 实现业务接口
public class UserServiceImpl implements UserService {@Overridepublic void saveUser(String username) {System.out.println("保存用户: " + username);}@Overridepublic String getUserById(Long id) {System.out.println("获取用户ID: " + id);return "用户" + id;}
}// 实现InvocationHandler接口,处理方法调用
public class JdkProxyHandler implements InvocationHandler {private final Object target; // 目标对象public JdkProxyHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 前置增强System.out.println("JDK动态代理: 方法调用前增强");// 调用目标方法Object result = method.invoke(target, args);// 后置增强System.out.println("JDK动态代理: 方法调用后增强");return result;}
}// 代理工厂类
public class JdkProxyFactory {public static Object getProxy(Object target) {return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),new JdkProxyHandler(target));}
}// 使用示例
public class JdkProxyExample {public static void main(String[] args) {UserService target = new UserServiceImpl();UserService proxy = (UserService) JdkProxyFactory.getProxy(target);proxy.saveUser("张三");proxy.getUserById(1L);}
}

3. 关键特性

  • 必须基于接口:代理对象实现了目标接口,而不是继承目标类
  • 反射调用:通过InvocationHandlerinvoke方法处理所有调用
  • 性能特点:首次生成代理类较快,但每次方法调用都需要通过反射,存在一定性能开销

二、CGLIB 代理:基于继承的代理实现

1. 核心原理

CGLIB(Code Generation Library)是一个强大的、高性能的代码生成库,Spring AOP 在 JDK 动态代理无法使用时会选择使用 CGLIB。CGLIB 通过继承目标类生成子类的方式实现代理,因此可以代理没有实现接口的类。

CGLIB 代理的生成过程主要涉及:

  • 使用 ASM 字节码生成框架动态生成目标类的子类
  • 重写父类的方法,在方法调用前后插入增强逻辑
  • 使用MethodInterceptor接口处理方法调用

2. 代码实现示例

下面是一个使用 CGLIB 代理的示例:

// 目标类(没有实现接口)
public class OrderService {public void createOrder(String orderNo) {System.out.println("创建订单: " + orderNo);}
}// 实现MethodInterceptor接口,处理方法调用
public class CglibInterceptor implements MethodInterceptor {@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {// 前置增强System.out.println("CGLIB代理: 方法调用前增强");// 调用目标方法(注意这里使用methodProxy.invokeSuper而不是method.invoke)Object result = proxy.invokeSuper(obj, args);// 后置增强System.out.println("CGLIB代理: 方法调用后增强");return result;}
}// 代理工厂类
public class CglibProxyFactory {public static <T> T getProxy(Class<T> targetClass) {Enhancer enhancer = new Enhancer();enhancer.setSuperclass(targetClass);enhancer.setCallback(new CglibInterceptor());return (T) enhancer.create();}
}// 使用示例
public class CglibProxyExample {public static void main(String[] args) {OrderService proxy = CglibProxyFactory.getProxy(OrderService.class);proxy.createOrder("ORD12345");}
}

3. 关键特性

  • 基于继承:代理对象继承自目标类,因此不能代理 final 类或方法
  • 字节码生成:使用 ASM 直接生成字节码,运行时不需要反射调用
  • 性能特点:首次生成代理类较慢(需要生成字节码并加载),但运行时性能较好

三、Spring 中的代理策略选择

Spring AOP 在选择代理方式时遵循以下策略:

  1. 默认优先使用 JDK 动态代理:如果目标对象实现了至少一个接口
  2. 自动切换到 CGLIB 代理:如果目标对象没有实现任何接口
  3. 强制使用 CGLIB 代理:可以通过配置proxy-target-class="true"@EnableAspectJAutoProxy(proxyTargetClass = true)

配置示例

// Java配置方式
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true) // 强制使用CGLIB代理
public class AppConfig {// 配置Bean和切面
}// XML配置方式
<aop:aspectj-autoproxy proxy-target-class="true"/>

四、性能对比与适用场景

1. 性能对比

  • 首次代理生成:JDK 动态代理较快(反射机制),CGLIB 较慢(需要生成字节码)
  • 方法调用:JDK 动态代理通过反射调用,性能稍低;CGLIB 直接调用,性能较高
  • 长期使用:如果代理对象需要被频繁调用,CGLIB 的总体性能更优

2. 适用场景

  • JDK 动态代理适用场景

    • 目标对象实现了接口
    • 代理对象主要用于接口方法的调用
    • 对首次代理生成速度有较高要求
  • CGLIB 代理适用场景

    • 目标对象是普通类(没有实现接口)
    • 需要代理类中的所有方法
    • 代理对象会被频繁调用,对运行时性能要求较高

五、特殊情况处理

1. 无法代理 final 类 / 方法

由于 CGLIB 通过继承实现代理,因此无法代理 final 类或 final 方法。如果尝试代理 final 类,Spring 会抛出AopConfigException

2. 混合使用接口和类

当一个类既实现了接口,又有一些非接口方法时,需要特别注意:

  • 如果使用 JDK 动态代理,只能代理接口中定义的方法
  • 如果使用 CGLIB 代理,可以代理所有方法(包括非接口方法)

3. 构造函数增强

CGLIB 支持对构造函数进行增强,而 JDK 动态代理只能对方法进行增强。

六、源码分析与理解

1. Spring 中的代理创建逻辑

Spring 在创建代理时主要通过ProxyFactory类实现,核心代码如下:

public class ProxyFactory extends ProxyCreatorSupport {public Object getProxy() {return createAopProxy().getProxy();}protected final synchronized AopProxy createAopProxy() {if (!this.active) {activate();}return getAopProxyFactory().createAopProxy(this);}
}

2. 代理方式选择源码

DefaultAopProxyFactory类负责根据条件选择代理方式:

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {@Overridepublic AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {Class<?> targetClass = config.getTargetClass();if (targetClass == null) {throw new AopConfigException("TargetSource cannot determine target class: " +"Either an interface or a target is required for proxy creation.");}// 如果目标类是接口或已经是JDK代理类,则使用JDK代理if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {return new JdkDynamicAopProxy(config);}// 否则使用CGLIB代理return new ObjenesisCglibAopProxy(config);}else {// 默认使用JDK代理return new JdkDynamicAopProxy(config);}}
}

七、总结与最佳实践

1. 核心要点总结

  • JDK 动态代理基于接口,CGLIB 基于继承
  • Spring 默认优先使用 JDK 动态代理,无法使用时切换到 CGLIB
  • 可以通过配置强制使用 CGLIB 代理
  • CGLIB 首次生成代理类较慢,但运行时性能更优

2. 最佳实践建议

  • 优先使用接口:设计类时尽量通过接口定义行为,便于使用 JDK 动态代理
  • 谨慎使用 final:避免将类或方法声明为 final,以免影响 CGLIB 代理
  • 性能敏感场景:如果代理对象会被频繁调用,考虑使用 CGLIB 并缓存代理实例
  • 调试与监控:在开发和测试阶段,注意观察代理方式的选择是否符合预期

通过深入理解 JDK 动态代理和 CGLIB 的原理与应用,我们可以更好地掌握 Spring AOP 的核心机制,在实际项目中做出更合适的技术选择,提高系统的可维护性和性能。

希望这篇博客能够帮助你更好地理解和记忆 Spring 代理机制的相关知识!如果有任何疑问或需要进一步探讨的地方,欢迎留言交流。

http://www.dtcms.com/wzjs/359574.html

相关文章:

  • 小说网站充值接口怎么做的sem推广托管公司
  • 日本代购网站怎么做的电脑优化大师下载安装
  • 广州做啊里巴巴网站多少钱上海百度推广开户
  • 西安分销商城网站建设阿里巴巴国际站运营
  • 建设公共网站的目的云南网站建设百度
  • 杰奇小说网站建设网站seo优化发布高质量外链
  • wordpress 双语网站网络营销方式与工具有哪些
  • pp下载安装 app优化seo哪家好
  • 做h5场景的网站宁波seo外包推广软件
  • 找做模型方案去哪个网站安仁网络推广
  • 东莞宣传网站成都官网seo厂家
  • 山东德州网站建设哪家便宜seo推广培训课程
  • 做网站能赚到流量费吗网站搭建的流程
  • 网站加载百度地图合肥seo公司
  • 网站开发不让搜索引擎域名ip查询查网址
  • 做网站一定要有营业执照吗百度网盘官方下载
  • 上海酒店团购网站建设东莞seo外包公司
  • 淘宝便宜的团购网站建设班级优化大师是干什么用的
  • 美食静态网站设计论文百度怎么推广自己的产品
  • wordpress 多说 代码什么是搜索引擎优化的核心
  • 上海嘉定网站建设淘宝关键词优化技巧
  • 网站怎样秒收录中国十大电商平台排名
  • 女装网站建设昆明优化网站公司
  • 网站开发怎样验收郑州百度推广代理公司
  • 电商网站开发背景微信怎么推广
  • 衣服品牌logo大全广州排前三的seo公司
  • 制作荧光字网站如何注册网站免费注册
  • 做网站营销公司网络营销案例分享
  • 龙岗 网站建设哪安装百度
  • 中国建筑装饰百强排名seo点击软件手机