我是spring的新手,我使用https://start.spring.io/创建了一个新的spring boot项目,没有任何依赖关系,解压缩了zip文件并在IntelliJ IDEA中打开了该项目。我没有做任何进一步的配置。我现在正在尝试使用@PostConstruct方法设置bean-但是,该方法永远不会被spring调用。
这些是我的课程:
SpringTestApplication.java
package com.habichty.test.testspring; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication public class SpringTestApplication { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(SpringTestApplication.class, args); context.getBean(TestBean.class).testMethod(); } }
TestBean.java
package com.habichty.test.testspring; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; @Component public class TestBean { private final Logger log = LoggerFactory.getLogger(this.getClass()); private int a = 1; public TestBean() { log.debug("Constructor of TestBean called."); } @PostConstruct public void init() { log.debug("init()-Method of TestBean called."); a = 2; } public void testMethod() { log.debug("Test Method of TestBean called. a=" + a); } }
当我启动应用程序时,这是我的输出:
:: Spring Boot :: (v1.5.9.RELEASE) 2018-01-22 13:15:57.960 INFO 12035 --- [ main] c.h.t.testspring.SpringTestApplication : Starting SpringTestApplication on pbtp with PID 12035 (/home/pat/prj/testspring/testspring/target/classes started by pat in /home/pat/prj/testspring/testspring) 2018-01-22 13:15:57.962 DEBUG 12035 --- [ main] c.h.t.testspring.SpringTestApplication : Running with Spring Boot v1.5.9.RELEASE, Spring v4.3.13.RELEASE 2018-01-22 13:15:57.962 INFO 12035 --- [ main] c.h.t.testspring.SpringTestApplication : No active profile set, falling back to default profiles: default 2018-01-22 13:15:58.018 INFO 12035 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@2931522b: startup date [Mon Jan 22 13:15:58 CET 2018]; root of context hierarchy 2018-01-22 13:15:58.510 DEBUG 12035 --- [ main] com.habichty.test.testspring.TestBean : Constructor of TestBean called. 2018-01-22 13:15:58.793 INFO 12035 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup 2018-01-22 13:15:58.822 INFO 12035 --- [ main] c.h.t.testspring.SpringTestApplication : Started SpringTestApplication in 1.073 seconds (JVM running for 2.025) 2018-01-22 13:15:58.822 DEBUG 12035 --- [ main] com.habichty.test.testspring.TestBean : Test Method of TestBean called. a=1 2018-01-22 13:15:58.826 INFO 12035 --- [ Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@2931522b: startup date [Mon Jan 22 13:15:58 CET 2018]; root of context hierarchy 2018-01-22 13:15:58.828 INFO 12035 --- [ Thread-1] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
如您所见,spring会初始化TestBean并执行testMethod()-但不会调用以@PostConstruct注释的init()-Method。
我究竟做错了什么?任何帮助都非常感谢。
更新1 在我的application.properties中,我已配置:
logging.level.com = DEBUG
将其更改为 logging.level.root = DEBUG会 导致更大的日志。但是,它仍然不包含我的init()方法的调试消息。
更新2 添加了package和import语句。
更新3 为了进一步说明这不是日志记录问题,我在代码中添加了一个新的int,该代码应通过init()-Method进行更改。据我了解@PostConstruct批注的概念,应该在执行任何其他方法之前执行它。结果,testMethod()的输出现在应该包含 a = 2 。在更新的输出中,您可能会发现情况并非如此。
更新4 这是我的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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.habichty.test.testspring</groupId> <artifactId>springTest</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springTest</name> <description>springTest</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </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> </project>
输出java -version:
java -version
java version "9.0.1" Java(TM) SE Runtime Environment (build 9.0.1+11) Java HotSpot(TM) 64-Bit Server VM (build 9.0.1+11, mixed mode)
由于Java9中的新模块系统SpringBoot-1.5.9无法处理,@PostConstruct因为注释类不在类路径中。问题(或类似问题)在此处和此处进行描述。有几种解决方法:
SpringBoot-1.5.9
@PostConstruct
使用Java8运行该应用程序, 或者如果仍在Java9上运行该应用程序:
javax.annotation:javax.annotation-api向POM 添加依赖项,或
javax.annotation:javax.annotation-api