Springboot依賴注入筆記

結合Autowired和Service註解

public interface IUser {
    void say();
}

@Service
public class Student implements IUser {

    @Override
    public void say() {
        System.out.println("I'm a student");
    }
}

@Component
@Order(value = 3)
public class Entry implements CommandLineRunner {
    public Log log = LogFactory.getLog(Entry.class);

    @Autowired
    IUser user;

    @Override
    public void run(String... args) throws Exception {
        user.say();
    }
}

 

若是要在構造函數中就須要訪問注入的變量,那麼Autowired的位置就要放到構造函數上spring

@Component
@Order(value = 3)
public class TestService {
    private final IUser user;

    @Autowired
    public void TestService (IUser user) {
        user.say();
    }
}

 

自定義注入的掃描範圍

要注意Springboot掃描包的時候默認是從啓動類(通常是Application)目錄開始往下掃描,也就意味着若是Bean不在Application目錄的下層,是不會被掃描到的。跨域

這種狀況會提示:springboot

Description:
Field xxx in xxxxxx required a bean of type 'xxxxxx' that could not be found.

Action:
Consider defining a bean of type 'xxxxxxxxxxxxxx' in your configuration.

 

不過這也不是沒法改變的,咱們手動指定掃描範圍便可:框架

@SpringBootApplication
@ComponentScan(basePackages={"springbootdemo.basic","anotherspringbootdemo.basic"})
public class Application {

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

範圍列表中不要忘記添加原來的目錄,及啓動類的包範圍。maven

另外,這個ComponentScan不是必須放到啓動類上,只要能夠被掃描到便可。ide

 

經過Configuration的方式

經過Configuration也能夠實現「跨域」的注入方式(即package不在一個範圍內)函數

/**
* Springboot會掃描標有Configuration註解的類
* 該類中標有Bean註解的方法,返回值會被做爲被注入項
* 至於這個Bean的注入項,在方法裏面return就是。
*/
@Configuration
public class TestConfig{
    
    @Bean
    public IUser user(){
        return new Teacher();
    }

    //有依賴關係的Bean也很簡單
    //這個IDepartment依賴IUser
    @Bean
    public IDepartment(){
        return new Development(user());
    } 
}

/*調用*/
public class TestClass{

    @Autowired
    IUser user;
    
    public void run(String... args) throws Exception {
        user.say();
    }
}

 

上面的Configuration雖然解決了「跨域」注入,但Configuration註解仍是要求放到調用的項目中。ui

不少時候當咱們須要依賴一個第三方jar包,並想要實現自動注入的時候,咱們並不想再去手動寫Configuration,畢竟若是多個地方引用這個jar包,每一處都須要這樣處理。spa

能不能一勞永逸呢?code

使用Springboot中的框架時,例如使用ES,咱們發現雖然並無聲明ElasticSearchTemplate,可是卻能夠直接使用

這裏有一篇不錯的講解 https://www.jianshu.com/p/346cac67bfcc

假設第三方項目是ProjectA,應用方是ProjectB

 如今ProjectA有 類TestTemplate

package ProjectA;

public class TestTemplate{

    public void test() {
        System.out.println("GO TEST");
    }
}

 

ProjectB須要注入並使用TestTemplate,固然確定要先添加maven的依賴(忽略),調用邏輯

package ProjectB;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import springbootdemo.common.TestTemplate;

@Component
public class Entry implements CommandLineRunner {
    
    @Autowired
    private TestTemplate aa;

    @Override
    public void run(String... args) throws Exception {
        aa.test();
    }
}

 

這時候運行ProjectB的話確定是會報錯的,由於找不到TestTemplate的注入結果,即便在TestTemplate上添加註解也是同樣。

咱們直接給出一個簡單的解決方案

①在ProjectA中新建一個自動配置類 TestAutoConfiguration

package ProjectA;

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class TestAutoConfiguration {
    @Bean
    @ConditionalOnMissingBean
    public TestTemplate testTemplate(){
        return new TestTemplate();
    }
}

 

②在ProjectA的資源目錄src/main/resources下建立目錄META-INF/spring.factories

 

內容:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
ProjectA.TestAutoConfiguration

如今再執行,一切OK!

相關文章
相關標籤/搜索