首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring中太多构造函数参数

Spring中太多构造函数参数
EN

Stack Overflow用户
提问于 2018-03-10 09:20:46
回答 1查看 2.7K关注 0票数 4

在我的代码中有一个Bean管理。Admin的一个操作是创建_Task_s和_start_ing。

任务执行的操作相当复杂。因此,它被分成几个不同的步骤类。

这就是我的代码的样子

代码语言:javascript
复制
public interface Admin{
    void start();

    //other methods
}

public class AdminImpl implements Admin{
    private BeanA bean1;
    private BeanB bean2;
    //other fields

    public Admin(BeanA bean1,
        BeanB bean2,
        BeanC bean3
        //Lot more parameters
        BeanO bean15
    ){
        this.bean1 = bean1;
        this.bean2 = bean2;
        //and so on
    }

    public void start(){
        return new Task(bean1, bean2, bean3,...).start()
    }

    //other methods
}

public class Task{
    private BeanA bean1;
    private BeanB bean2;
    //other fields
    public Task(BeanA bean1,
        BeanB bean2,
        BeanC bean3
        //Lot more parameters
    ){
        //bind parameters to fields
    }

    public void start(){
        new Step1(bean1, bean2,.. other parameters).do();
        new Step2(bean3, bean7,.. other parameters).do();
        //more steps
    }
}

@Configuration
public class MyConfiguration{
    @Bean
    public Admin admin(BeanA bean1, BeanB bean2....){
        return new AdminImpl(bean1, bean2...);
    }
}

如您所见,每个步骤类都有2或3个Bean依赖项。Step类不是Spring,因此它们是从Task传递的依赖项。任务也不是Spring,因此它从Admin获得依赖项。这导致Admin有太多的依赖项(~15)。

我试过这个:https://dzone.com/articles/autowiring-spring-beans-into-classes-not-managed-by-spring

基本上,您可以创建一个名为BeanUtil的服务Bean,即ApplicationContextAware。静态方法getBean使用ApplicationContext获取bean。

Step类现在如下所示:

代码语言:javascript
复制
class Step{
    public Step(){
        BeanA bean1 = BeanUtil.getBean(BeanA.class);
        BeanB bean2 = BeanUtil.getBean(BeanB.class);
    }

    public void do(){
        //do stuff 
    }
}

这解决了最初的问题,但后来我在测试方面遇到了困难。这就是测试类现在的样子。

代码语言:javascript
复制
 @ContextConfiguration(loader = AnnotationConfigContextLoader.class)
    public class Step1Test extends AbstractTestNGSpringContextTests {

        @Test
        public void test(){
            Step1 step = new Step().do();
        }

        @Configuration
        static class MockConfiguration {

            @Bean
            public BeanA beanA() {
                BeanA mockBeanA=Mockito.mock(BeanA.class);
                // set behavior of mock
                return mockBeanA;
            }

            @Bean
            public BeanUtil beanUtil(){
                return new BeanUtil();
            }
        }
    }

如果不创建不同的配置类,就不能更改不同测试用例的模拟行为。这就像是通过创造另一个问题来解决一个问题。

这是Spring开发人员面临的一个常见问题吗?在这个问题上,抽象级别较高的类最终具有太多的依赖关系?还是我的设计出了什么问题?什么是正确的方法来处理或避免这一点?

其他看似相似但不是的问题

编辑:我从user7得到的一个建议是,我将BeanX分组并将抽象传递给Admin。beans没有任何我可以利用的逻辑分组。此外,许多步骤都需要完全访问bean(访问接口中的所有方法)。这将导致抽象变得臃肿。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-03-10 10:27:21

您可以将步骤Spring作为原型bean(因为它们是有状态的,并且每次都需要不同的实例),并在任务bean中注入Provider<Step> (如果我正确理解,它可以是单例bean)。

例如:

代码语言:javascript
复制
public class Step1 {
    private Bean1 bean1;
    private Bean2 bean2;

    private final String someValue;
    private final String someOtherValue;

    public Step(String someValue, String someOtherValue) {
        this.someValue = someValue;
        this.someOtherValue = someOtherValue;
    }

    @Autowired
    public void setBean1(Bean1 bean1) {
        this.bean1 = bean1;
    }

    @Autowired
    public void setBean2(Bean2 bean2) {
        this.bean2 = bean2;
    }

    do() {
        // ...
    }
}

然后,在configuration类中,将各种步骤定义为bean,并使用需要的参数的方法:

代码语言:javascript
复制
@Bean
@Scope("prototype")
public Step1 step1(String someValue, String someOtherValue) {
    return new Step(someValue, someOtherValue);
}

在Task中,注入一个ObjectProvider<Step1>

代码语言:javascript
复制
private ObjectProvider<Step1> stepProvider;

public Service(ObjectProvider<Step1> step1Provider) {
    this.stepProvider = stepProvider;
}

public void start() {
    Step1 step1 = step1Provider.getObject("a", "b");
    step1.do();
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49207421

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档