在@Bean被调用之前,在bean初始化后调用方法。

huangapple go评论99阅读模式
英文:

Call method after bean initialization but before @Bean called

问题

@Configuration
public class MyAppConfiguration extends MyBaseAppConfiguration {
@Bean
public MyDAOBean getMyDAOBean() {
boolean isEmpty = myString.isEmpty();
return new MyDAOBean();
}
}

@Component
@ConfigurationProperties(prefix="hey")
@Getter
@Setter
public class MyBean {
private String myString;
}

public class MyBaseAppConfiguration {
@Autowired
private MyBean myBean;

  1. protected String myString;
  2. //I need some annotation to call this (@PostConstruct maybe?)
  3. public void setMyString() {
  4. this.myString = myBean.getMyString();
  5. }

}

I want to set myString with something that I got from myBean. So I need some annotation to call the method that sets this field after myBean is initialized but before getMyDAOBean is called. @PostConstruct currently works for this situation, but I need to be sure if it always works. Does it do the job, or is there something I don't know, and this is risky?

Please ignore the simplicity of the example. myBean.getMyString() in getMyDAOBean would be easier, but it's more complex in reality. Just focus on the problem.

Edit: How about the setter-injection way? Does it make any difference? Is it safer or something else?

public class MyBaseAppConfiguration {
protected String myString;

  1. @Autowired
  2. public void setMyString(MyBean myBean) {
  3. this.myString = myBean.getMyString();
  4. }

}

英文:
  1. @Configuration
  2. public class MyAppConfiguration extends MyBaseAppConfiguration {
  3. @Bean
  4. public MyDAOBean getMyDAOBean() {
  5. boolean isEmpty = myString.isEmpty();
  6. return new MyDAOBean();
  7. }
  8. }
  9. @Component
  10. @ConfigurationProperties(prefix="hey")
  11. @Getter
  12. @Setter
  13. public class MyBean {
  14. private String myString;
  15. }
  16. public class MyBaseAppConfiguration {
  17. @Autowired
  18. private MyBean myBean;
  19. protected String myString;
  20. //I need some annotation to call this (@PostConstruct maybe?)
  21. public void setMyString() {
  22. this.myString= myBean.getMyString();
  23. }
  24. }

I want to set myString with something that I got from myBean. So I need some annotation to call method that I set this field after myBean initiliazed but before getMyDAOBean called. @PostConstruct currently working for this situation but I need to be sure if it is always working. Does it do the job or there is something I don't know and this is risky?

Please ignore simplicity of example. myBean.getMyString() in getMyDAOBean would be more easy but It's more complex in real, just focus on the problem.

Edit: How about setter-injection way? Does it make any difference? More safety or else?

  1. public class MyBaseAppConfiguration {
  2. protected String myString;
  3. @Autowired
  4. public void setMyString(MyBean myBean) {
  5. this.myString= myBean.getMyString();
  6. }
  7. }

答案1

得分: 1

你可以将MyBean添加为构造函数注入。

  1. public class MyBaseAppConfiguration {
  2. protected String myString;
  3. @Autowired
  4. public MyBaseAppConfiguration(MyBean myBean){
  5. myString = myBean.getMyString();
  6. }
  7. }
英文:

You can add MyBean as a constructor injection.

  1. public class MyBaseAppConfiguration {
  2. protected String myString;
  3. @Autowired
  4. public MyBaseAppConfiguration(MyBean myBean ){
  5. myString = myBean.getMyString();
  6. }

}

答案2

得分: 1

The creation of the bean for MyDAOBean seems to have some dependency on a computed value based on the property of MyBean.

@Conditional 注解以及自定义条件可以用来执行所需的操作;在这种情况下是 myString.isEmpty()

  1. import org.springframework.context.annotation.Condition;
  2. import org.springframework.context.annotation.ConditionContext;
  3. import org.springframework.core.type.AnnotatedTypeMetadata;
  4. import java.util.Objects;
  5. public class MyStringIsEmpty implements Condition {
  6. @Override
  7. public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
  8. // 获取 MyBean 的 Spring Bean
  9. MyBean myBean = Objects.requireNonNull(context.getBeanFactory()).getBean(MyBean.class);
  10. // 获取 myString 属性
  11. String myString = myBean.getMyString();
  12. // 执行所需的评估
  13. boolean isEmpty = myString.isEmpty();
  14. return isEmpty; // 如果为 true,则创建该 Bean
  15. }
  16. }

使用自定义条件。

  1. import org.springframework.context.annotation.Bean;
  2. import org.springframework.context.annotation.Conditional;
  3. @Bean
  4. @Conditional(MyStringIsEmpty.class)
  5. public MyDAOBean getMyDAOBean() {
  6. return new MyDAOBean();
  7. }
英文:

The creation of the bean for MyDAOBean seems to have some dependency on a computed value based on the property of MyBean.

The @Conditional annotation alongside a custom condition can be used to do the operations required; myString.isEmpty() is this case.

  1. import org.springframework.context.annotation.Condition;
  2. import org.springframework.context.annotation.ConditionContext;
  3. import org.springframework.core.type.AnnotatedTypeMetadata;
  4. import java.util.Objects;
  5. public class MyStringIsEmpty implements Condition {
  6. @Override
  7. public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
  8. // Get the spring bean for MyBean
  9. MyBean myBean = Objects.requireNonNull(context.getBeanFactory()).getBean(MyBean.class);
  10. // Get the property of myString
  11. String myString = myBean.getMyString();
  12. // perform your desired evaluation
  13. boolean isEmpty = myString.isEmpty();
  14. return isEmpty; // if true, the bean will be created
  15. }
  16. }

Using the custom condition.

  1. import org.springframework.context.annotation.Bean;
  2. import org.springframework.context.annotation.Conditional;
  3. @Bean
  4. @Conditional(MyStringIsEmpty.class)
  5. public MyDAOBean getMyDAOBean() {
  6. return new MyDAOBean();
  7. }

huangapple
  • 本文由 发表于 2023年4月4日 15:46:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/75926752.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定