2017-02-09 17 views
11

Tôi đang sử dụng chú thích @Autowired dưới một hàm tạo lớp @Configuration.Cách đặt tham số hàm tạo @Autowired là "required = false" riêng lẻ

@Configuration 
public class MyConfiguration { 

    private MyServiceA myServiceA; 
    private MyServiceB myServiceB 

    @Autowired 
    public MyConfiguration(MyServiceA myServiceA, MyServiceB myServiceB){ 
    this.myServiceA = myServiceA; 
    this.myServiceB = myServiceB;  
    } 
} 

Spring documentation sais, tôi có thể tuyên bố xem phụ thuộc có chú thích là bắt buộc hay không.

Nếu tôi đánh dấu @Autowired chú thích dưới các nhà xây dựng như required=false, tôi nói rằng hai dịch vụ được autowired không phải (tùy theo từng sais tài liệu Spring):

@Autowired(required = false) 
public MyConfiguration(MyServiceA myServiceA, MyServiceB myServiceB){ 
    this.myServiceA = myServiceA; 
    this.myServiceB = myServiceB; 
} 

Từ tài liệu xuân :

Trong trường hợp của nhiều phương pháp đối số, thông số 'bắt buộc' là áp dụng cho tất cả các đối số.

Làm cách nào để đặt thuộc tính required cho từng thông số hàm tạo riêng lẻ? Bạn có cần sử dụng chú thích @Autowired trong mọi trường không?

Kính trọng,

Trả lời

11

Nếu bạn đang sử dụng Java 8 và Spring Framework 4, bạn có thể sử dụng Optional.

@Autowired 
public MyConfiguration(Optional<MyServiceA> myServiceA, Optional<MyServiceB> myServiceB){ 
    myServiceA.ifPresent(service->{this.myServiceA = service}); 
    myServiceB.ifPresent(service->{this.myServiceB = service}); 
} 
+0

nó sẽ gây ra lỗi NPE sau – Andrew

+3

@AndrewTobilko chắc chắn OP sẽ kiểm tra giá trị rỗng nếu anh ta đang xem xét sự phụ thuộc "tùy chọn". Bạn cũng có thể có các trường tùy chọn. Nhiều cách để đảm bảo bạn sẽ không nhận được NPE. – Strelok

+1

Tôi không muốn sử dụng 'Tùy chọn', nhưng cảm ơn câu trả lời của bạn;) – jcgarcia

11

cách tiếp cận Explicit

Về cơ bản, bạn có một bean mà có một số phụ thuộc cần thiết và bắt buộc. Cách được đề nghị để xử lý kịch bản này, không chỉ là các bean cấu hình mà còn chỉ là tạo một hàm tạo cho các phụ thuộc bắt buộc và sử dụng phép setter cho các tùy chọn.

public class MyConfiguration { 

    private final MyServiceA myServiceA; 
    private MyServiceB myServiceB 

    @Autowired 
    public MyConfiguration(MyServiceA myServiceA){ 
    this.myServiceA = myServiceA; 
    } 

    @Autowired(required = false) 
    public void setMyServiceB(MyServiceB myServiceB) { 
    this.myServiceB = myServiceB; 
    } 

} 

Với phương pháp này, bạn có thể dễ dàng kiểm tra lớp học mà không cần bất kỳ thư viện mô phỏng nào. Bạn có thể tạo một đối tượng trong trạng thái thử nghiệm bằng cách sử dụng hàm tạo và các bộ định tuyến tùy chọn.

Đặt @Autowired(required = false) trực tiếp trên trường và xóa trình thiết lập cũng sẽ hoạt động, nhưng vì bạn đang sử dụng phép dựng hàm tạo, tôi giả sử bạn muốn nêu rõ các phụ thuộc rõ ràng hơn.

ý tưởng bổ sung

Bạn cũng có thể xem xét sử dụng các loại tùy chọn để quấn phụ thuộc không bắt buộc. Nó là phổ biến trong số các nhà phát triển để giả định rằng nếu một lớp học có một tài sản, nó cần được thiết lập, mà rõ ràng là không đúng trong kịch bản của bạn. Để đánh dấu khả năng vắng mặt vì phụ thuộc đặc biệt rõ ràng hơn bạn có thể có thể sử dụng tùy chọn:

public class MyConfiguration { 

    private final MyServiceA myServiceA; 
    private Optional<MyServiceB> myServiceB 

    @Autowired 
    public MyConfiguration(MyServiceA myServiceA){ 
    this.myServiceA = myServiceA; 
    this.myServiceB = Optional.empty(); 
    } 

    @Autowired(required = false) 
    public void setMyServiceB(MyServiceB myServiceB) { 
    this.myServiceB = Optional.ofNullable(myServiceB); 
    } 

} 

Một số người chống lại bằng cách sử dụng loại Optional cho thuộc tính của lớp (chủ yếu là do answer from Brian Goetz này), nhưng vào cuối ngày nó phải là quyết định của toàn đội sẽ làm việc trong dự án.

+0

Xin lỗi, nhưng dưới dạng tài liệu Spring sais:" Chỉ một hàm tạo (tối đa) của bất kỳ lớp bean nào có thể mang chú thích này, cho biết hàm tạo khi được sử dụng làm bean Spring " – jcgarcia

+2

Lưu ý rằng chỉ có một hàm tạo trong ví dụ. Chú thích thứ hai nằm trên phương thức setter. Bạn có thể chú thích như nhiều setters như bạn muốn. –

+0

Lỗi của tôi, tôi không nhìn thấy phương pháp thứ hai như một setter. Tất nhiên, tôi biết rằng tôi có thể chú thích như nhiều setters như tôi muốn và như nhiều tài sản như tôi muốn ... nhưng đó là những gì tôi đang cố gắng để tránh! – jcgarcia

Các vấn đề liên quan