Spring @Autowired违反DRY原则。可以做些什么?

时间:2018-04-22 10:05:19

标签: java spring spring-boot dry

我使用的代码中的一些控制器和服务有很多@Autowired个依赖项。有两种流行的自动装配方式 - Autowire字段和Autowire构造函数。 在第一种情况下,您复制了注释@Autowired

public class SomeController {
    @Autowired
    private SomeService1 someService1;
    @Autowired
    private SomeService2 someService2;
    @Autowired
    private SomeService3 someService3;
}

在第二种情况下,你创建了一个丑陋且无用的构造函数。

public class SomeController {
    private final SomeService1 someService1;
    private final SomeService2 someService2;
    private final SomeService3 someService3;

    @Autowired
    public SomeController(SomeService1 someService1,
                          SomeService2 someService2,
                          SomeService3 someService3) {
        this.someService1 = someService1;
        this.someService2 = someService2;
        this.someService3 = someService3;
    }
}

当您有许多应该自动装配的字段时,情况会变得更糟。我同意很多依赖关系通常标志着一个糟糕的设计,但这不是我的问题。我想避免使用像@AutowireAll这样的代码重复,这个注释将自动装配所有可能自动装配的字段。我搜索了它,但无法找到。可能的代码看起来像

@AutowireAll
public class SomeController {
    private SomeService1 someService1;
    private SomeService2 someService2;
    private SomeService3 someService3;
}

如何避免代码重复?

2 个答案:

答案 0 :(得分:2)

使用Lombok注释@AllArgsConstructor

可以避免代码重复
@AllArgsConstructor
public class SomeController {
    private final SomeService1 someService1;
    private final SomeService2 someService2;
    private final SomeService3 someService3;
}

它适用于Spring / Spring Boot版本,在唯一的构造函数中不需要@Autowired。这些版本是Spring Boot 1.4 +,Spring 4.3 +

@AllArgsConstructor创建一个可能需要的构造函数(参见 Karol Dowbecki 在他的回答下的评论)。

缺点是,为了使用Lombok,您需要一个IDE插件。 Eclipse和IDEA都有这样的插件,但由于您不是唯一从事项目的开发人员,所有其他开发人员也需要它。

答案 1 :(得分:0)

如果只有一个构造函数,则不必使用@Autowired。默认情况下它将自动连接:

@Controller
public class SomeController {
  private final SomeService1 someService1;
  private final SomeService2 someService2;

  public SomeController(SomeService1 someService1, SomeService2 someService2) {
    this.someService1 = someService1;
    this.someService2 = someService2;
  }
}

根据docs, chapter 1.9.2. @Autowired

  

从Spring Framework 4.3开始,在这样的一个@Autowired注释   如果目标bean只定义一个,则不再需要构造函数   构造函数开头。但是,如果有几个构造函数   可用,至少有一个必须注释教导容器   一个人可以使用。