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也能夠實現「跨域」的注入方式(即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!