Java 应用依赖注入的正确spring引导方式是什么

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

我目前正在开发一个spring引导应用程序,该应用程序通过以下简化的示例将一些bean连接在一起:

@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();
            }
        });

    }
}