Backend Development 9 min read

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 Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Master Spring Boot 3: Real‑World @Lookup, @DeclareParents, @Timed & More

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>&lt;dependency&gt;
  &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
  &lt;artifactId&gt;spring-boot-starter-actuator&lt;/artifactId&gt;
&lt;/dependency&gt;
</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.

Lookup result
Lookup result
Metrics endpoint
Metrics endpoint
Configuration binding error
Configuration binding error
backendJavaSpring BootAnnotationsMicrometer
Spring Full-Stack Practical Cases
Written by

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.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.