Master Spring Boot 3: Real‑World @Lookup, @DeclareParents, @Timed & More
This article presents a curated collection of practical Spring Boot 3 examples, demonstrating how to use the @Lookup, @DeclareParents, @Timed/@Counted, and @ConfigurationPropertiesBinding annotations with complete code snippets, configuration steps, and runtime results for backend developers.
Spring Boot 3.4.2 provides several powerful annotations that simplify bean management and metrics collection. Below are practical examples that illustrate their usage.
@Lookup
The @Lookup annotation can be placed on a method to indicate that the method should retrieve a bean from the container at runtime, typically a prototype bean from a singleton.
<code>@Component
@Scope("prototype")
public class PrototypeBean {
}
@Component
public abstract class BusinessBean {
@Lookup
public abstract PrototypeBean getInstance();
}
@Component
public 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());
}
}
</code>Running the application prints three different prototype instances, confirming that each call goes through BeanFactory#getBean to obtain a fresh bean.
@DeclareParents
The @DeclareParents annotation allows you to introduce a new parent type (usually an interface) to matching target classes, enabling automatic implementation of that interface.
<code>public interface DAO {
void query();
}
public class CommonDAO implements DAO {
public void query() {
System.err.println("通用查询接口服务...");
}
}
@Component
public class UserDAO {
}
@Aspect
@Component
public class DeclareParentsAspect {
@DeclareParents(value = "com.pack.common_use.annotation.UserDAO", defaultImpl = CommonDAO.class)
private DAO dao;
}
@Component
public class DeclareParentsRunner implements CommandLineRunner {
private final UserDAO userDAO;
public DeclareParentsRunner(UserDAO userDAO) {
this.userDAO = userDAO;
}
@Override
public void run(String... args) throws Exception {
if (userDAO instanceof DAO dao) {
dao.query();
}
}
}
</code>The runner prints the message from CommonDAO , showing that UserDAO now implements DAO without modifying its source code.
@Timed and @Counted
Since Spring 6, the Web module includes Micrometer. The @Timed and @Counted annotations automatically create metrics via an Aspect. They can be enabled either by defining TimedAspect / CountedAspect beans or, more conveniently, by adding the spring-boot-starter-actuator dependency.
<code><dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</code>Enable the annotations in application.yml :
<code>management:
observations:
annotations:
enabled: true
</code>Define a controller that uses both annotations:
<code>@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");
}
}
</code>After invoking the two endpoints, the metrics are visible at /actuator/metrics , showing the recorded execution time and count.
@ConfigurationPropertiesBinding
The @ConfigurationPropertiesBinding annotation marks a custom converter that transforms configuration values before they are bound to a bean annotated with @ConfigurationProperties .
<code>@Component
@ConfigurationProperties(prefix = "pack.common")
public class CommonProperties {
private String author;
private App app; // getters & setters
}
</code>Configuration file:
<code>pack:
common:
author: xxgg
app: Spring Boot3实战案例200讲,1.0.0
</code>Because the app property is a comma‑separated string, a custom converter is needed:
<code>@Component
@ConfigurationPropertiesBinding
public class AppConverter implements Converter<String, App> {
@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]);
}
}
</code>With this converter, Spring can bind the string to an App object successfully.
These examples demonstrate how Spring Boot’s advanced annotations can be leveraged to manage prototype beans, introduce interfaces dynamically, collect metrics, and customize property binding, providing powerful tools for backend development.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.