当前位置:首页 > 科技  > 软件

Spring一个强大便捷的代理工厂类,你用过吗?

来源: 责编: 时间:2024-04-30 08:42:23 336观看
导读环境:Spring6.1.21. 简介在Spring框架中,AOP(面向切面编程)是一种强大的编程范式,它允许开发者在不修改原有代码的情况下,为程序添加额外的功能,如日志记录、事务管理、安全控制等。实际开发中常用实现AOP配置方式:基于XML在

环境:Spring6.1.2ynD28资讯网——每日最新资讯28at.com

1. 简介

在Spring框架中,AOP(面向切面编程)是一种强大的编程范式,它允许开发者在不修改原有代码的情况下,为程序添加额外的功能,如日志记录、事务管理、安全控制等。ynD28资讯网——每日最新资讯28at.com

实际开发中常用实现AOP配置方式:ynD28资讯网——每日最新资讯28at.com

  • 基于XML

在早期的Spring版本中,开发者常常使用XML配置文件来定义切面、通知和目标对象之间的关联。通过配置<aop:config>、<aop:aspect>、<aop:before>等标签,可以轻松地实现AOP的各种功能。如下示例:ynD28资讯网——每日最新资讯28at.com

<aop:config>  <aop:aspect id="myAspect" ref="aBean">    <aop:pointcut id="businessService"      expression="execution(* com.pack.service.*.*(..))"/>    <aop:before pointcut-ref="businessService" method="monitor"/>  </aop:aspect></aop:config>
  • 基于注解

通过在切面类和方法上使用如@Aspect、@Before、@After等注解,可以更加简洁地定义AOP的相关配置。这种方式不仅减少了XML配置的工作量,还使得代码更加清晰易读。如下示例:ynD28资讯网——每日最新资讯28at.com

@Component@Aspectpublic class LogAspect {  @Pointcut("execution(* save(..))")  private void logPc() {}  @Around("logPc()")  public Object process(ProceedingJoinPoint pjp) throws Throwable {    Object ret = null ;    System.out.println("before log...") ;    ret = pjp.proceed() ;    System.out.println("after log...") ;    return ret ;  }}

以上是Spring提供的2中方式来声明AOP配置方式。但如果你需要一种更加灵活和可配置性,那么Spring还提供了一个非常方便强大的ProxyFactoryBean类,该类特别适合那些需要更多自定义和控制的场景,例如当你需要为特定的Bean创建代理,或者需要在不修改原始代码的情况下为现有类添加额外的功能时。ynD28资讯网——每日最新资讯28at.com

2. 实战案例

ProxyFactoryBean与其他Spring FactoryBean实现一样,引入了一个间接级别。如果定义了名为pack的ProxyFactoryBean,那么引用pack的对象看不到ProxyFactoryBean实例本身,而是由ProxyFactoryBean#getObject()方法实现创建的对象。此方法创建一个AOP代理,用于包装目标对象。ynD28资讯网——每日最新资讯28at.com

2.1 属性配置

ProxyFactoryBean提供了很多属性,让你可以灵活的配置代理对象。该对象继承了ProxyConfig,一些关键的属性是由ProxyConfig定义。ynD28资讯网——每日最新资讯28at.com

  • proxyTargetClass:如果要代理目标类,而不是目标类的接口,则为true。如果此属性值设置为true,则会创建CGLIB代理。
  • optimize:控制是否对通过CGLIB创建的代理应用积极的优化。除非完全理解相关AOP代理如何处理优化,否则不应该轻松地使用此设置。目前仅用于CGLIB代理。它对JDK动态代理没有影响。
  • frozen:如果代理配置被冻结,则不再允许更改该配置。此属性的默认值为false,因此允许更改(例如添加额外的通知)。
  • exposeProxy:确定是否应在ThreadLocal中公开当前代理,以便目标可以访问它。如果目标需要获取代理,并且exposeProxy属性设置为true,则该目标可以使用AoPontext.currentProxy()方法获取代理对象。
  • proxyInterface:字符串接口名称的数组。
  • interceptorNames:要应用的Advisor、拦截器或其他建议名称的字符串数组。

接下来将从2方面介绍ProxyFactoryBean的使用,代理接口与代理类。2.2 代理接口ynD28资讯网——每日最新资讯28at.com

要通过ProxyFactoryBean创建代理,你至少需要涉及到下面几点(类):ynD28资讯网——每日最新资讯28at.com

  • 需要被代理的目标bean类。
  • 一个Advisor或者Advice,增强部分。
  • 指定要代理的接口。

如下示例:ynD28资讯网——每日最新资讯28at.com

public interface ICommonDAO {  void save() ;}@Component("commonDAOTarget")public class CommonDAOImpl implements ICommonDAO {  @Override  public void save() {    System.out.println("save operator...") ;  }}@Componentpublic class LogInterceptor implements MethodInterceptor {  @Override  public Object invoke(MethodInvocation invocation) throws Throwable {    System.out.println("before log...") ;    Object ret = invocation.proceed() ;    System.out.println("after  log...") ;    return ret ;  }}@Configurationpublic class AppConfig {  @Bean  // 由于上面已经定义了CommonDAOImpl,而这里的FactoryBean#getObject返回的  // 也是一个实现了ICommonDAO接口的对象,所以需要加上@Primary  @Primary  ProxyFactoryBean commonDAO(@Qualifier("commonDAOTarget") CommonDAOImpl commonDAOTarget) throws Exception {    ProxyFactoryBean proxy = new ProxyFactoryBean() ;    proxy.setProxyInterfaces(new Class<?>[] {ICommonDAO.class}) ;    proxy.setTarget(commonDAOTarget) ;    proxy.setInterceptorNames("logInterceptor") ;    return proxy ;  }}

测试ynD28资讯网——每日最新资讯28at.com

ICommonDAO dao = context.getBean(ICommonDAO.class) ;dao.save() ;// 输出before log...save operator...after  log...

2.3 代理类

如果我们的目标没有实现接口,那么我们只能通过CGLIB进行代理,通过设置proxyTargetClass属性为true。CGLIB代理通过在运行时生成目标类的子类来工作。Spring将这个生成的子类配置为将方法调用委托给原始目标。如下示例:ynD28资讯网——每日最新资讯28at.com

@Component("commonDAOTarget")public class CommonDAO {  public void save() {    System.out.println("save operator...") ;  }}@Bean@PrimaryProxyFactoryBean commonDAO(@Qualifier("commonDAOTarget") CommonDAO commonDAOTarget) throws Exception {  ProxyFactoryBean proxy = new ProxyFactoryBean() ;  proxy.setTarget(commonDAOTarget) ;  proxy.setInterceptorNames("logInterceptor") ;  // 代理类,可以不设置  proxy.setProxyTargetClass(true) ;  return proxy ;}

查看最终的CommonDAO是否是通过CGLIB代理ynD28资讯网——每日最新资讯28at.com

CommonDAO dao = context.getBean(CommonDAO.class) ;System.out.println(dao.getClass()) ;

输出结果ynD28资讯网——每日最新资讯28at.com

class com.pack.aop.create.ProxyFactoryBeanTest2$CommonDAO$$SpringCGLIB$$1

CGLIB代理通过在运行时生成目标类的子类来工作。但需要注意以下事项:ynD28资讯网——每日最新资讯28at.com

  • final 类不能被代理,因为它们不能被扩展。
  • final方法无法提供增强,因为它们不能被覆盖。
  • 不能增强private方法,因为它们不能被重写。
  • 不可见的方法,通常是来自不同包的父类中的包私有方法,不能被增强,因为它们实际上是私有的。

2.4 模糊匹配拦截器

在上面配置拦截器时,我们都是指定的具体拦截器,其实我们还可以使用通配符,指定拦截器。如下示例:ynD28资讯网——每日最新资讯28at.com

@Component("global_log")public class LogInterceptor implements MethodInterceptor {}@Component("global_auth")public class AuthInterceptor implements MethodInterceptor {}// ProxyFactoryBena配置ProxyFactoryBean commonDAO() throws Exception {  ProxyFactoryBean proxy = new ProxyFactoryBean() ;  // 注意:这里的通配符必须是最后,你不能放到其它位置  proxy.setInterceptorNames("global_*") ;  return proxy ;}

以上ProxyFactoryBean在初始化时,会自动查找容器中beanName以global_开头的所有Bean对象。ynD28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-86683-0.htmlSpring一个强大便捷的代理工厂类,你用过吗?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: HTTP 协议是怎么来的?最开始是什么样子?又是如何一步步发展 HTTP3

下一篇: 一种避免写大量CRUD方法的新思路

标签:
  • 热门焦点
  • 俄罗斯:将审查iPhone等外国公司设备 保数据安全

    iPhone和特斯拉都属于在各自领域领头羊的品牌,推出的产品也也都是数一数二的,但对于一些国家而言,它们的产品可靠性和安全性还是在限制范围内。近日,俄罗斯联邦通信、信息技术
  • 轿车从天而降电动车主被撞身亡 超速抢道所致:现场视频让网友吵翻

    近日,上海青浦区法院判决轿车从天而降电动车主被撞身亡案,轿车车主被判有期徒刑一年。案件显示当时男子驾驶轿车在上海某路段行驶,前车忽然转弯提速超车,
  • 三言两语说透设计模式的艺术-单例模式

    写在前面单例模式是一种常用的软件设计模式,它所创建的对象只有一个实例,且该实例易于被外界访问。单例对象由于只有一个实例,所以它可以方便地被系统中的其他对象共享,从而减少
  • 量化指标是与非:挽救被量化指标扼杀的技术团队

    作者 | 刘新翠整理 | 徐杰承本文整理自快狗打车技术总监刘新翠在WOT2023大会上的主题分享,更多精彩内容及现场PPT,请关注51CTO技术栈公众号,发消息【WOT2023PPT】即可直接领取
  • 三言两语说透柯里化和反柯里化

    JavaScript中的柯里化(Currying)和反柯里化(Uncurrying)是两种很有用的技术,可以帮助我们写出更加优雅、泛用的函数。本文将首先介绍柯里化和反柯里化的概念、实现原理和应用
  • 每天一道面试题-CPU伪共享

    前言:了不起:又到了每天一到面试题的时候了!学弟,最近学习的怎么样啊 了不起学弟:最近学习的还不错,每天都在学习,每天都在进步! 了不起:那你最近学习的什么呢? 了不起学弟:最近在学习C
  • Temu起诉SHEIN,跨境电商战事升级

    来源 | 伯虎财经(bohuFN)作者 | 陈平安日前据外媒报道,拼多多旗下跨境电商平台Temu正对竞争对手SHEIN提起新诉讼,诉状称Shein&ldquo;利用市场支配力量强迫服装厂商与之签订独家
  • “又被陈思诚骗了”

    作者|张思齐 出品|众面(ID:ZhongMian_ZM)如今的国产悬疑电影,成了陈思诚的天下。最近大爆电影《消失的她》票房突破30亿断层夺魁暑期档,陈思诚再度风头无两。你可以说陈思诚的
  • iQOO Neo8 Pro即将开售:到手价3099元起 安卓性能最强旗舰

    5月23日,iQOO如期举行了新品发布会,全新的iQOO Neo8系列也正式与大家见面,包含iQOO Neo8和iQOO Neo8 Pro两个版本,其中标准版搭载高通骁龙8+,而Pro版更
Top