簡體   English   中英

如何在配置類中使自動裝配工作?

[英]How do I make Autowired work inside a Configuration class?

我試圖在@Configuration類中自動裝配標記為@Service的屬性(myService),但得到了NullPointer。
相反,如果我將myService自動連接到非配置類中,則沒有問題。

這是我在自動裝配時遇到的問題@Service:

package com.myapp.resources;

@Service
class MyService {
    public List<String> getRoutingKeys() {
        List<String> routingKeys;

        //Do stuff

        return routingKeys;
    }

    public String aMethod() {

        return "hello";
    }
}

這是@Configuration類,在這里我無法自動連接服務

package com.myapp.messaging;

import com.myapp.resources;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;

@Configuration
public class RabbitConfiguration {
    private List<String> routingKeys = writeRoutingKeys();

    @Autowired
    private MyService myService;

    private List<String> writeRoutingKeys() {
        boolean test = myService == null;
        System.out.println("is the service null? " + test); //output: true!!!

        return myService.getRoutingKeys(); //here I get a NullPointer
    }

    //Methods with bean declarations for RabbitMQ
 }

如果有幫助,這是我的主類:

package com.myapp;

import com.myapp.resources;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

import java.util.List;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        ConfigurableApplicationContext appContext = SpringApplication.run(Application.class, args);

        MyService myService = (MyService) appContext.getBean(MyService.class);

        boolean test = myService == null;
        System.out.println("is the service null? " + test); //output: false

        //Do stuff
    }
}

如果有幫助,這里是另一個類(@RestController),我可以在其中自動裝配服務

package com.myapp.resources;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    @Autowired
    private MyService myService;

    @GetMapping("/endpoint")
    public String myRestMethod() {
        boolean test = myService == null;
        System.out.println("is the service null? " + test); //output: false

        return myService.aMethod();
    }
}

我也嘗試過在Configuration類中添加@ComponentScan,但是我仍然得到一個NullPointer

package com.myapp.messaging;

//list of imports...

@Configuration
@ComponentScan("com.myapp.demo")
public class RabbitConfiguration {
   @Autowired
   private MyService myService;

   //...
}

我建議通過任何需要它的@Bean創建方法來注入服務:

@Bean
public MyBean create(MyService myService)

然后將該服務傳遞到writeRoutingKeys(MyService myService)方法中以進行相應處理。

每個文檔:

@Configuration類在上下文的初始化過程中很早就被處理,強制以這種方式注入依賴項可能導致意外的早期初始化。 只要有可能,請像上面的示例中那樣使用基於參數的注入。

Spring僅在實例化bean之后或實例時注入依賴項(取決於是否使用構造函數注入)。 但是,您現在正在字段初始化期間訪問依賴項MyService ,這在初始化bean之前發生。因此,由於尚未注入,它無法在字段初始化期間訪問MyService

您可以通過更改為使用構造函數注入並routingKeys在構造函數內部初始化routingKeys來簡單地修復它:

@Configuration
public class RabbitConfiguration {

    private List<String> routingKeys ;
    private MyService myService;

    @Autowired
    public RabbitConfiguration(MyService myService){
        this.myService = myService
        this.routingKeys = writeRoutingKeys();
    }

    private List<String> writeRoutingKeys() {
        return myService.getRoutingKeys(); 
    }
 }

或者簡單地:

@Autowired
public RabbitConfiguration(MyService myService){
    this.myService = myService
    this.routingKeys = myService.getRoutingKeys();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM