I think spring-boot 3.0.5 does not fully conform to the contract defined by the jakarta.annotation.PostConstruct annotation (from jakarta.annotation-api-2.1.1.jar).
The Javadoc of the annotation says: "Only one method in a given class can be annotated with this annotation.".
However, it is possible to annotate at least two methods of a given class which is registered as a @Component or @Bean with this annotation and all annotated methods are executed after the bean is initialized after calling SpringApplication.run().
Shouldn't the Spring application refuse to start then if it finds more than one method annotated with @PostConstruct on any bean class (although this would restrict developers to only having one @PostConstruct method per bean class)?
This is my POM:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.tutego</groupId>
<artifactId>date4u</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>date4u</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.shell</groupId>
<artifactId>spring-shell-starter</artifactId>
<version>3.0.0-M2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
This is my bean class:
import org.springframework.stereotype.Component;
import jakarta.annotation.PostConstruct;
@Component
public class MyComponent {
@PostConstruct
void postConstruct1() {
System.out.println("post construct1");
}
@PostConstruct
void postConstruct2() {
System.out.println("post construct2");
}
}
And my application class:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Date4uApplication {
public static void main(String[] args) {
SpringApplication.run(Date4uApplication.class, args);
}
}
Comment From: wilkinsona
Support for @PostConstruct is a Spring Framework feature. If you think it should behave differently, please open a Spring Framework issue.
Comment From: quaff
@PostConstructmethods should be public
Spring Framework doesn't require that, it supports any access modifier include private.