【问题标题】:spring boot - @PostConstruct not called on @Componentspring boot - 未在 @Component 上调用 @PostConstruct
【发布时间】:2018-01-22 11:28:21
【问题描述】:

我是 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() 方法的调试消息。

UPDATE 2添加了包和导入语句。

更新 3 为了进一步说明这不是日志记录问题,我在代码中添加了一个新的 int,它应该由 init() 方法更改。据我了解@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 "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)

【问题讨论】:

  • 你试过debug吗?
  • 为了确保使用的是最新的源代码,请您在Maven Projects/Lifecycle 中运行maven clean 吗?
  • 刚刚尝试重现 - 结果相同,init 方法未被调用。
  • 对我来说,它在 Java8 (1.8.0_141) 上运行良好,但在 Java9 (9.0.1) 上运行失败。
  • @yegodm 我可以确认这一点。用 openjdk8 替换了我的 Java9-jdk,现在它可以工作了。非常感谢你!你应该考虑添加这个作为答案,我会接受它。

标签: java spring spring-boot


【解决方案1】:

由于Java9 中的新模块系统SpringBoot-1.5.9 无法处理@PostConstruct,因为注释类不在类路径上。问题(或类似问题)描述为herehere。有几种方法可以解决:

  • 使用 Java8 运行应用程序,
    或者,如果仍在 Java9 上:
  • javax.annotation:javax.annotation-api 依赖添加到 POM,或者
  • 升级到包含该依赖项的更新的 Spring-Boot 2.0.0+ 版本(在撰写本文时仍为 PRERELEASE);

【讨论】:

【解决方案2】:

我知道这个问题已经解决了,但是因为这是我在谷歌上搜索这个问题时出现的第一个 Stackoverflow 问题,所以我将把它留在这里:

我遇到了同样的问题,我的错误是我的包名中有错字。我的调用名称的类与我的 SpringBootApplication 类具有不同的包名。所以我的主要应用程序没有找到我的组件。

因此,如果您遇到类似问题,请务必检查您的包名称。

【讨论】:

    【解决方案3】:

    我猜你没有定义类似的东西

    logging.level.root=debug
    

    在您的 application.properties 中?

    没有 = 没有日志

    带=

    2018-01-22 12:34:06.117 DEBUG 8516 --- [main] com.example.demo.TestBean  : Constructor of TestBean called. 
    ...
    2018-01-22 12:34:06.117 DEBUG 8516 --- [main] com.example.demo.TestBean : init()-Method of TestBean called. 
    ...
    2018-01-22 12:34:06.241 DEBUG 8516 --- [main]  com.example.demo.TestBean : Test Method of TestBean called.
    

    【讨论】:

    • 我确实用 logging.level.com=debug 配置了这个。由于构造函数和 testMethod() 正在使用调试日志并且它们显示正确,因此这也应该适用于 init() 方法。但是,我尝试了您的方法,但是“调用了 TestBean 的 init()-Method”。仍然没有出现在我的日志中。
    • 这很令人困惑。
    • 你能在你的导入中编辑吗?`也许有什么问题。
    • 好的,刚刚添加了我的包和导入语句。
    • 我有完全相同的配置:(
    【解决方案4】:

    如果您使用的是 Java 9 或更高版本,那么在代码中使用 @PostConstruct 和 @PreDestroy 时会遇到错误。

    Eclipse 无法导入@PostConstruct 或@PreDestroy

    使用 Java 9 及更高版本时,javax.annotation 已从其默认类路径中删除。这就是 Eclipse 找不到它的原因。


    解决方案

    1. 下载 javax.annotation-api-1.3.2.jar

    https://search.maven.org/remotecontent?filepath=javax/annotation/javax.annotation-api/1.3.2/javax.annotation-api-1.3.2.jar

    1. 将 JAR 文件复制到项目的 lib 文件夹中

    使用以下步骤将其添加到您的 Java 构建路径。

    1. 右键单击您的项目,选择属性

    2. 在左侧,单击 Java 构建路径

    3. 在对话框的顶部中心,单击库

    4. 单击类路径,然后单击添加 JAR ...

    5. 导航到 JAR 文件 /lib/javax.annotation-api-1.3.2.jar

    6. 点击确定,然后点击应用并关闭

    Eclipse 将重新构建您的项目,并解决相关的构建错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-18
      • 2018-04-11
      • 1970-01-01
      • 2015-05-01
      • 2015-04-02
      • 2022-12-05
      • 1970-01-01
      • 2015-12-24
      相关资源
      最近更新 更多