大数跨境
0
0

SpringBoot冷门但逆天的5个神级注解,老司机都在偷偷用!

SpringBoot冷门但逆天的5个神级注解,老司机都在偷偷用! Spring全家桶实战案例
2025-05-18
0
导读:震惊!Spring Boot隐藏的宝藏!这5个冷门注解能让你的代码起飞!
Spring Boot 3实战案例锦集PDF电子书已更新至100篇!
图片

🎉🎉《Spring Boot实战案例合集》目前已更新125个案例,我们将持续不断的更新。文末有电子书目录。

💪💪永久更新承诺

我们郑重承诺,所有订阅合集的粉丝都将享受永久免费的后续更新服务

💌💌如何获取
订阅我们的合集点我订阅,并通过私信联系我们,我们将第一时间将电子书发送给您。

→ 现在就订阅合集

环境:SpringBoot3.4.2



1. @Lookup

该注解只能应用于方法上,用于指示“查找”方法的注解。

如何查找?

根据当前方法的返回值或者该注解配置的value属性值(beanName),在容器中查找对应的bean,通过BeanFactory#getBean进行备案的查找。如下示例:

首先,我们定义如下的原型Bean:

@Component@Scope("prototype")public class PrototypeBean {}

其次,定义使用@Lookup注解的bean:

@Componentpublic abstract class BusinessBean {  @Lookup  public abstract PrototypeBean getInstance()  ;}

最后,定义如下Runner进行测试:

@Componentpublic class LookupRunner implements CommandLineRunner {  // 注入抽象类  private final BusinessBean businessBean ;  public LookupRunner(BusinessBean businessBean) {    this.businessBean = businessBean;  }  @Override  public void run(String... args) throws Exception {      System.err.println(this.businessBean.getInstance()) ;    System.err.println(this.businessBean.getInstance()) ;    System.err.println(this.businessBean.getInstance()) ;  }}

运行结果

首先,Spring底层对我们的抽象类做了特殊处理(创建了代理,如果抽象类中没有使用@Lookup注解的方法,那么将会报错),当我们每次调用getInstance方法时都会通过BeanFactory#getBean从容器中获取bean,这样就确保了在单例bean中正确的获取多例bean。

有关@Lookup更多的详细介绍,请查看下面这篇文章:

有多少人用过Spring的@Lookup注解?

2. @DeclareParents

使用 @DeclareParents 注解用于声明匹配的类型拥有一个新的父类型。简单点说,那些符合条件的类将会拥有一个新的父类(自动帮你实现一个指定的接口)。如下示例:

首先,我们定义一个接口及对应的实现类:

public interface DAO {  void query() ;}public class CommonDAO implements DAO {  public void query() {    System.err.println("通用查询接口服务...") ;  }}

其次,定义如下的一个类:

@Componentpublic class UserDAO {}

我们接下来要做的是定义切面,让UserDAO类自动的实现DAO接口,并且该接口的对应实现使用CommonDAO。

@Aspect@Componentpublic class DeclareParentsAspect {  @DeclareParents(value = "com.pack.common_use.annotation.UserDAO", defaultImpl = CommonDAO.class)  private DAO dao ;}

说明:value配置是Aspectj 切点表达式,这里将值匹配UserDAO。我们还可以使用如下的表达式:

# 匹配common_user包及其子包下的所有类com.pack.common_user.*+

注意,只支持类级别。

最后,通过如下的Runner测试:

@Componentpublic class DeclareParentsRunner implements CommandLineRunner {  private final UserDAO userDAO ;  public DeclareParentsRunner(UserDAO userDAO) {    this.userDAO = userDAO;  }  public void run(String... args) throws Exception {    if (userDAO instanceof DAO dao) {      dao.query() ;     }  }}

运行结果

3. @Timed/@Counted

从Spring6.x起,Spring Web模块默认引入micrometer-core依赖(度量指标库),而这两个注解都是在该包中。这2个注解都对应的有一个Aspect切面,要启用这2个注解功能可以通过如下2种方式:

  • 自定义对应的Bean对象TimedAspect,CountedAspect

  • 引入actuator依赖,将自动的配置这2个切面(推荐

      

接下来,我们将通过actuator的方式来演示:

首先,引入actuator依赖:

<dependency>  <groupId>org.springframework.boot</groupId>  <artifactId>spring-boot-starter-actuator</artifactId></dependency>

还需要开启如下配置:

management:  observations:    annotations:      enabledtrue

其次,定义如下的Controller接口:

@RestController@RequestMapping("/tcs")public class TimedCountedAController {  @Timed(    description = "统计执行时间"    value = "exec_time"    histogram = true,     extraTags = {"pack""time"})  @GetMapping("/time")  public ResponseEntity<?> time() throws Exception {    TimeUnit.MILLISECONDS.sleep(new Random().nextInt(1000)) ;    return ResponseEntity.ok("success") ;  }  @Counted(description = "统计执行次数", value = "exec_count", extraTags = {"pack""count"})  @GetMapping("/count")  public ResponseEntity<?> count() throws Exception {    return ResponseEntity.ok("success") ;  }}

接下来,我们随意的访问上面2个接口。然后,再访问/ac/metrics接口。

我们定义的2个指标已经在metrics端点中。

最后,分别查看这2个指标:

当接口发生异常,那么通过该指标端点也是可以查看的。

3.4 @ConfigurationPropertiesBinding

用于标识那些需要配置 @ConfigurationProperties 绑定(例如转换器 Converters)的 bean 的限定符。

现在有如下的配置类及配置属性值:

@Component@ConfigurationProperties(prefix = "pack.common")public class CommonProperties {  private String author ;  private App app ;  // getters, setters}

配置文件:

pack:  common:    author: xxgg    app: Spring Boot3实战案例200讲,1.0.0

类中app属性是App对象类型,而配置文件中则是由逗号分割的字符串,这在默认情况下是是无法进行转换的,如下错误:

在不修改配置属性方式的情况下,要解决该问题你可以自定义类型转换器,如下示例:

@Component@ConfigurationPropertiesBindingpublic class AppConverter implements Converter<StringApp> {  @Override  public App convert(String source) {    if (source == null) {      return null ;    }    String[] values = source.split(",") ;    if (values.length < 2) {      return null ;    }    return new App(values[0], values[1]) ;  }}

该类使用了@ConfigurationPropertiesBinding注解(必须使用)。

定义了该特殊的ben后,容器在绑定属性值时就能通过该转换器进行处理了。



以上是本篇文章的全部内容,如对你有帮助帮忙点赞+转发+收藏

推荐文章

10个SQL优化技巧,性能提升300%

掌握 Spring Boot 7个高级知识点

高级开发!秒杀@RequestBody,万能参数解析器

高级开发!Spring Boot处理枚举类型,支持JPA、MyBatis、Jackson

强大!基于Spring Boot通过责任链模式,实现复杂接口动态编排能力

王炸!Spring AI+MCP 三步实现智能体开发

性能调优实战:Spring Boot 通过多线程处理SQL IN语句大量值的优化方案

王炸!Spring AI+Tools 一分钟实现CRUD智能助手

注意!@ExceptionHandler异常处理注解有新功能了

高级开发!自定义组件通过3种方式解决Spring Boot配置文件中的敏感数据

如何在Spring Boot中优雅地加载配置?这些方法你必须掌握!

【声明】内容源于网络
0
0
Spring全家桶实战案例
Java全栈开发,前端Vue2/3全家桶;Spring, SpringBoot 2/3, Spring Cloud各种实战案例及源码解读
内容 832
粉丝 0
Spring全家桶实战案例 Java全栈开发,前端Vue2/3全家桶;Spring, SpringBoot 2/3, Spring Cloud各种实战案例及源码解读
总阅读7
粉丝0
内容832