我是Springboot的新手,我只是偶然发现了这段代码,并想知道这是不是很好的做法以及幕后发生的事情......
User.java
@Getter
@Setter
@NoArgsConstructor
public class User
{
private String name;
private String role;
private String custom;
}
Config1.java:
@Configuration
public class Config1
{
@Bean
@Primary
User createUser(){
User user = new User();
user.setName("John");
user.setRole("dev");
return user;
}
}
Config2.java:
@Configuration
public class Config2
{
@Bean
User modifyUser(User user){
user.setCustom("second configuration using the same bean ?");
return user;
}
}
结束点:
@Autowired
private User user;
当我检查用户变量时,我注意到所有3个属性都被填充。我假设Spring使用Config1来创建bean,然后将引用传递给Config2。但是我想知道这是否是正常的行为,还有其他办法吗?
上下文:在我的情况下,Config1是一个包含在项目中的外部源,我没有任何控制权。我想从我的application.yml文件中设置额外的属性,因此Config2。 (我在我的例子中省略了@value)
*编辑我最后做的事情
Config2.java
@Configuration
public class Config2
{
@Autowired
private User user;
@PostConstruct
Private void init(){
user.setCustom("second configuration using the same bean ?");
}
}
答案 0 :(得分:2)
我认为这不是好习惯。您可以使用基本的弹簧生命周期机制,这可以帮助您实现目标,而不会给出“我应该这样做”的感觉吗?
现在,回答你的问题(或类似的问题)。
这里发生了什么?
您的评估是正确的。 Config1
正在创建User
类型的bean,并通过Config2
参数提供给modifyUser
的{{1}} bean。这有效地在ApplicationContext,createUser和modifyUser中创建两个bean,它们引用同一个bean(或同一个bean的不同代理)。
这样不好吗?
呃,我不会说这很糟糕,但如果你问我,它肯定会有一个臭味。如果您的目标是进一步配置在其他地方创建的bean,我可以考虑更好的方法。还有哪些其他选择?
我会推荐以下选项之一:
BeanPostProcessor
- 此接口提供了一种方法,可用于在实例化postProcessAfterInitialization
后自定义bean。 JavaDoc相当全面,应该提供有关如何使用该方法的足够信息,所以我不会在这里重复它。一旦你创建了一个你想要的实现,你就可以将它注册为一个带有ApplicationContext的bean(类似于你已经完成的那样。@PostConstruct
注释。 user
课程中的方法。 Spring的ApplicationContext将识别这一点,并在构造和初始化Configuration类之后调用此方法。这种方法的签名必须返回Config2
并且不带参数,但是您的配置类可以自动装入void
,以便在所述方法中使用。在return语句和user参数之外,你几乎可以使用User
方法。