Java 应用依赖注入的正确spring引导方式是什么
我目前正在开发一个spring引导应用程序,该应用程序通过以下简化的示例将一些bean连接在一起:Java 应用依赖注入的正确spring引导方式是什么,java,spring,spring-boot,dependency-injection,Java,Spring,Spring Boot,Dependency Injection,我目前正在开发一个spring引导应用程序,该应用程序通过以下简化的示例将一些bean连接在一起: @Component @Order(0) public class PlayingFieldByBeans implements CommandLineRunner { @Override public void run(String... arg0) throws Exception { List<String> names = new Array
@Component
@Order(0)
public class PlayingFieldByBeans implements CommandLineRunner {
@Override
public void run(String... arg0) throws Exception {
List<String> names = new ArrayList<>();
names.add("Alex");
names.add("Benedict");
names.add("Chloe");
System.out.println("Printing from lazy beans variant: ");
names.forEach(n -> {
System.out.println(player(n));
});
}
@Bean
@Lazy
public Player player(String name) {
return new Player(name, shoes());
}
@Bean
@Lazy
private Shoes shoes() {
return new Shoes("Adidas");
}
}
PlayerComponent类如下所示:
@Component
public class PlayerComponent {
@Autowired
private ShoesComponent shoesComponent;
public Player player(String name) {
return new Player(name, shoesComponent.shoes());
}
}
ShoesComponent与PlayerComponent类非常相似
出于可维护性和TDD的目的,我不确定在这里使用spring框架最合适的方式是什么
问题:
鉴于玩家和鞋子bean需要的不仅仅是一行初始化、多个设置、对其他bean的多个依赖等,那么设计和连接它们的最佳方式是什么
编辑-基于建议
添加了一个配置类来绑定bean:
@Configuration
public class BeanConfiguration {
@Bean
@Lazy
public Player player(String name) {
return new Player(name, shoes());
}
@Bean
@Lazy
public Shoes shoes() {
return new Shoes("Adidas");
}
}
以及匹配的执行类:
@Component
@Order(2)
public class PlayingFieldByConfiguration implements CommandLineRunner {
@Autowired
private BeanConfiguration beanConfiguration;
@Override
public void run(String... arg0) throws Exception {
List<String> names = new ArrayList<>();
names.add("Alex");
names.add("Benedict");
names.add("Chloe");
System.out.println("Printing from component variant: ");
names.forEach(n -> {
System.out.println(beanConfiguration.player(n));
});
}
}
一个解决方案是,如果我们想像安德烈·斯洛博迪安尼克(AndriySlobodyanyk)所提到的那样创建不同的品牌,那么我们可以在以后改变玩家豆和鞋子的范围
@Configuration
public class BeanConfiguration {
@Bean
@Lazy
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public Player player(String name) {
return new Player(name, shoes());
}
@Bean
@Lazy
public Shoes shoes() {
return new Shoes("Adidas");
}
}
若由于您提到真实案例场景更容易编译,所以上述内容还不够,那个么另一个选项是使用FactoryBean
public class PlayerFactoryBean implements FactoryBean<Player> {
private String name;
private Shoes shoes;
public void setName(String name) {
this.name = name;
}
public void setShoes(Shoes shoes) {
this.shoes = shoes;
}
@Override
public Player getObject() throws Exception {
//initialization logic goes here
System.out.println("Creating bean using factory");
return new Player(name, shoes);
}
@Override
public Class<Player> getObjectType() {
return Player.class;
}
@Override
public boolean isSingleton() {
return false;
}
}
你看过spring中的@Configuration组件了吗?看起来这就是你需要的,把所有的bean初始化代码放在那里。用你的建议更新了这个问题,谢谢你,bean默认是单例的,即使returnnew创建了多个对象。使用@ScopeBeanDefinition.SCOPE\u原型
@Configuration
public class BeanConfiguration {
@Bean
@Lazy
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public Player player(String name) {
return new Player(name, shoes());
}
@Bean
@Lazy
public Shoes shoes() {
return new Shoes("Adidas");
}
}
public class PlayerFactoryBean implements FactoryBean<Player> {
private String name;
private Shoes shoes;
public void setName(String name) {
this.name = name;
}
public void setShoes(Shoes shoes) {
this.shoes = shoes;
}
@Override
public Player getObject() throws Exception {
//initialization logic goes here
System.out.println("Creating bean using factory");
return new Player(name, shoes);
}
@Override
public Class<Player> getObjectType() {
return Player.class;
}
@Override
public boolean isSingleton() {
return false;
}
}
@Configuration
public class BeanConfiguration {
@Bean
@Lazy
public Shoes shoes() {
return new Shoes("Adidas");
}
@Bean
public PlayerFactoryBean playerFactoryBean(){
PlayerFactoryBean pfb = new PlayerFactoryBean();
pfb.setShoes(shoes());
return pfb;
}
}
@Component
@Order(2)
public class PlayingFieldByConfiguration implements CommandLineRunner {
@Autowired
private PlayerFactoryBean factoryBean;
@Override
public void run(String... arg0) throws Exception {
List<String> names = new ArrayList<>();
names.add("Alex");
names.add("Benedict");
names.add("Chloe");
System.out.println("Printing from component variant: ");
names.forEach(n -> {
try {
factoryBean.setName(n);
System.out.println(factoryBean.getObject());
} catch (Exception e) {
e.printStackTrace();
}
});
}
}