@ Bean mong muốn là null khi được tham chiếu trong hàm tạo của bean khác


89

Dưới đây là một đoạn mã mà tôi thử và tham khảo bean ApplicationProperties của mình. Khi tôi tham chiếu nó từ phương thức khởi tạo thì nó là null, nhưng khi được tham chiếu từ phương thức khác thì nó tốt. Cho đến bây giờ tôi không gặp vấn đề gì khi sử dụng bean tự động này trong các lớp khác. Nhưng đây là lần đầu tiên tôi cố gắng sử dụng nó trong hàm tạo của một lớp khác.

Trong đoạn mã dưới đây applicationProperties là null khi được gọi từ hàm tạo nhưng khi được tham chiếu trong phương thức convert thì không. Tôi còn thiếu gì

@Component
public class DocumentManager implements IDocumentManager {

  private Log logger = LogFactory.getLog(this.getClass());
  private OfficeManager officeManager = null;
  private ConverterService converterService = null;

  @Autowired
  private IApplicationProperties applicationProperties;


  // If I try and use the Autowired applicationProperties bean in the constructor
  // it is null ?

  public DocumentManager() {
  startOOServer();
  }

  private void startOOServer() {
    if (applicationProperties != null) {
      if (applicationProperties.getStartOOServer()) {
        try {
          if (this.officeManager == null) {
            this.officeManager = new DefaultOfficeManagerConfiguration()
              .buildOfficeManager();
            this.officeManager.start();
            this.converterService = new ConverterService(this.officeManager);
          }
        } catch (Throwable e){
          logger.error(e);  
        }
      }
    }
  }

  public byte[] convert(byte[] inputData, String sourceExtension, String targetExtension) {
    byte[] result = null;

    startOOServer();
    ...

Dưới đây là đoạn mã từ ApplicationProperties ...

@Component
public class ApplicationProperties implements IApplicationProperties {

  /* Use the appProperties bean defined in WEB-INF/applicationContext.xml
   * which in turn uses resources/server.properties
   */
  @Resource(name="appProperties")
  private Properties appProperties;

  public Boolean getStartOOServer() {
    String val = appProperties.getProperty("startOOServer", "false");
    if( val == null ) return false;
    val = val.trim();
    return val.equalsIgnoreCase("true") || val.equalsIgnoreCase("on") || val.equalsIgnoreCase("yes");
  }

Câu trả lời:


179

Autowiring (liên kết từ bình luận của Dunes) xảy ra sau khi xây dựng một đối tượng. Do đó, chúng sẽ không được thiết lập cho đến khi hàm tạo đã hoàn thành.

Nếu bạn cần chạy một số mã khởi tạo, bạn sẽ có thể kéo mã trong hàm khởi tạo vào một phương thức và chú thích phương thức đó bằng @PostConstruct.


3
Như nó nói trong tài liệu - static.springsource.org/spring/docs/2.5.x/api/org/…
Dunes

Cảm ơn liên kết, tôi sẽ thêm nó vào câu trả lời cho dễ tìm.
nicholas.hauschild

2
Cảm ơn bạn, tôi vẫn chưa đọc được câu nói quan trọng "Ruộng được tiêm ngay sau khi xây xong một hạt đậu ...". Tôi đã thử chú thích @PostConstruct và nó chính xác là những gì tôi cần.
hairyone

cũng rất vui khi đăng một liên kết về @PostConstruct static.springsource.org/spring/docs/3.0.0.M3/reference/html/…
Timofey

@Tim Cảm ơn! Tôi đã cập nhật liên kết câu trả lời lên phiên bản Spring 3.2 và tôi cũng đã thêm phiên bản Spring 3.2 vào liên kết của bạn.
nicholas.hauschild

44

Để có các phụ thuộc được đưa vào tại thời điểm xây dựng, bạn cần phải có hàm tạo của bạn được đánh dấu bằng @Autowiredchú thích như vậy.

@Autowired
public DocumentManager(IApplicationProperties applicationProperties) {
  this.applicationProperties = applicationProperties;
  startOOServer();
}

2
Trên thực tế, tôi nghĩ rằng đây nên là câu trả lời ưa thích. Phương pháp tiêm phụ thuộc dựa trên hàm tạo rất phù hợp cho các thành phần bắt buộc. Sử dụng cách tiếp cận này, khung lò xo cũng sẽ có thể phát hiện các phụ thuộc tuần hoàn trên các thành phần (như trong A phụ thuộc vào B, B phụ thuộc vào C, C phụ thuộc vào A). Kiểu tiêm sử dụng bộ định thời hoặc các trường tự động có thể đưa các bean chưa được khởi tạo hoàn toàn vào trường của bạn, khiến mọi thứ trở nên lộn xộn hơn một chút.
Seakayone
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.