java 在 Spring Context @Configuration 中运行 void setup 方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38957851/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 03:56:47  来源:igfitidea点击:

Run a void setup method in Spring Context @Configuration

javaspringspring-mvcspring-bootannotations

提问by ptimson

I wish to perform a couple of setup methods within my Spring Context.

我希望在我的 Spring Context 中执行几个设置方法。

I currently have the following code but it doesn't work as I am saying they are beansand have no return type.

我目前有以下代码,但它不起作用,因为我说它们是beans并且没有返回类型。

@Configuration
@Component
public class MyServerContext {

    ...

    // Works
    @Bean
    public UserData userData() {
        UserData userData = new AWSUserDataFetcher(urlUtil()).fetchUserData();
        return userData;
    }   

    // Doesn't work
    @Bean
    public void setupKeyTrustStores() {
        // Setup TrustStore & KeyStore
        System.setProperty(SYS_TRUST_STORE, userData().get(TRUST_STORE_PATH));
        System.setProperty(SYS_TRUST_STORE_PASSWORD, userData().get(TRUST_STORE_PASSWORD));
        System.setProperty(SYS_KEY_STORE, userData().get(KEY_STORE_PATH));
        System.setProperty(SYS_KEY_STORE_PASSWORD, userData().get(KEY_STORE_PASSWORD));

        // Prevents handshake alert: unrecognized_name
        System.setProperty(ENABLE_SNI_EXTENSION, "false");
    }

    ...

}

How can I run this method automatically by the @Configurationcontext without the @Beanannotation?

如何在@Configuration没有@Bean注释的情况下通过上下文自动运行此方法?

回答by Milo? Milivojevi?

You can use the @PostConstructannotation instead of @Bean:

您可以使用@PostConstruct注释代替@Bean

@Configuration
@Component
public class MyServerContext {

    @Autowired
    private UserData userData; // autowire the result of userData() bean method

    @Bean
    public UserData userData() {
        UserData userData = new AWSUserDataFetcher(urlUtil()).fetchUserData();
        return userData;
    }   

    @PostConstruct
    public void setupKeyTrustStores() {
        // Setup TrustStore & KeyStore
        System.setProperty(SYS_TRUST_STORE, userData.get(TRUST_STORE_PATH));
        System.setProperty(SYS_TRUST_STORE_PASSWORD, userData.get(TRUST_STORE_PASSWORD));
        System.setProperty(SYS_KEY_STORE, userData.get(KEY_STORE_PATH));
        System.setProperty(SYS_KEY_STORE_PASSWORD, userData.get(KEY_STORE_PASSWORD));

        // Prevents handshake alert: unrecognized_name
        System.setProperty(ENABLE_SNI_EXTENSION, "false");
    }

    ...

}

回答by SkyWalker

Use @PostConstruct instead of @bean

使用@PostConstruct 代替@bean

@PostConstruct

@PostConstruct

Due to the Weld Referenceinjection and initialization happens in this order;

由于Weld Reference注入和初始化按此顺序发生;

  1. First, the container calls the bean constructor (the default constructor or the one annotated @Inject), to obtain an instance of the bean.
  2. Next, the container initializes the values of all injected fields of the bean.
  3. Next, the container calls all initializer methods of bean (the call order is not portable, don't rely on it).
  4. Finally, the @PostConstructmethod, if any, is called.
  1. 首先,容器调用 bean 构造函数(默认构造函数或注解 @Inject 的构造函数),以获取 bean 的实例。
  2. 接下来,容器初始化 bean 的所有注入字段的值。
  3. 接下来,容器调用bean的所有初始化方法(调用顺序不可移植,不要依赖)。
  4. 最后,@PostConstruct调用该方法(如果有)。

So, the purpose of using @PostConstructis clear; it gives you a chance to initialize injected beans, resources etc.

所以,使用的目的@PostConstruct很明确;它让您有机会初始化注入的 bean、资源等。

public class Person {

    // you may have injected beans, resources etc.

    public Person() {
        System.out.println("Constructor is called...");
    }

    @PostConstruct
    public void init() {
        System.out.println("@PostConstruct is called...");
    } }

So, the output by injecting a Person bean will be;

因此,注入 Person bean 的输出将是;

Constructor is called...

@PostConstruct is called...

构造函数被称为...

@PostConstruct 被称为...

One important point about @PostConstructis, it won't be invoked if you try to inject and initialize bean through producer methods. Because using a producer method means that you are programmatically creating, initializing, and injecting your bean with new keyword.

重要的一点@PostConstruct是,如果您尝试通过生产者方法注入和初始化 bean,它将不会被调用。因为使用生产者方法意味着您正在以编程方式创建、初始化和注入带有 new 关键字的 bean。

Resource Link:

资源链接:

  1. CDI Dependency Injection @PostConstruct and @PreDestroy Example
  2. Why use @PostConstruct?
  1. CDI 依赖注入 @PostConstruct 和 @PreDestroy 示例
  2. 为什么使用@PostConstruct?