javascript
spring 5企业级开发实战pdf_SpringBoot实战5-Spring基础-配置与注入
接上篇《SpringBoot實戰4-Spring基礎-IoC容器》,通過對Spring容器的學習,并利用上文新建的項目學習Spring Bean的配置和注入的各種方式。
2 Spring Bean的配置
2.1 注解配置 - @Component
當類注解@Component、@Service、@Repository、@Controller,Spring容器會自動掃描(通過@ComponentScan實現,Spring Boot已經做好了配置)并將他們注冊成受容器管理的Bean。
@Componentpublic class SomeService { public void doSomething(){ System.out.println("我做了一些工作"); }}@Component、@Service、@Repository、@Controller在當前示例中是完全等同的:
@Servicepublic class SomeService2 { public void doSomething(){ System.out.println("我也做了一些工作"); }}上面的@Component和@Service都沒有給Bean命名,Spring容器會自動命名為類名的第一個字母小寫,即someService和someService2,我們一般沒有必要去改Bean的名稱,使用默認的Bean名即可,當然也可以通過@Component("SomeService")來設置。
@Service、@Repository、@Controller這三個注解組合了@Component注解,都是@Component語義上的特例。
- @Component:被注解類是“組件”;
- @Controller:被注解類是“控制器”;
- @Service:被注解類是“服務”;
- @Repository:被注解類是“數據倉庫”。
2.2 Java配置 - @Configuration和@Bean
在類上注解了@Configuration(@Component的特例,也會被容器自動掃描)作為配置類上,使用@Bean標注在方法上讓方法的返回值作為Bean的實例。如我們現在有另外一個類:
@Getter //lombok注解,給屬性生成get方法@Setter //lombok注解,給屬性生成set方法public class AnotherService { private String person; public AnotherService(String person) { this.person = person; } public void doAnotherThing(){ System.out.println(person + "做了另外的事情"); }}我們的用Java配置的如下:
@Configurationpublic class JavaConfig { @Bean public AnotherService anotherService(){ return new AnotherService("wyf"); }}同樣我們也沒有給Bean命名,Spring會將方法名anotherService默認成方法名,若需要修改使用@Bean(name = "AnotherService")。
2.3 依賴注入
2.3.1 自動注入- @Autowired
容器已經為我們創建了SomeService、AnotherService和SomeService2的Bean,那其他的Bean怎么注入使用呢?
- 注解注入我們有個AnnotationInjectionService要使用SomeService和AnotherService的Bean,我們只要在AnnotationInjectionService構造器上注解@Autowired即可注入參數里需要的Bean:
使用構造器注入是Spring推薦的注入方式,當然我們也可以在屬性上注解@Autowired來注入Bean:
@Servicepublic class AnnotationPropertyInjectionService { @Autowired private SomeService someService; @Autowired private SomeService2 someService2; public void doMyThing(){ someService.doSomething(); someService2.doSomething(); }}我們也可以在set方法上注解@Autowired來注入Bean:
@Servicepublic class AnnotationSetterInjectionService { private SomeService someService; private SomeService2 someService2; @Autowired public void setSomeService(SomeService someService) { this.someService = someService; } @Autowired public void setSomeService2(SomeService2 someService2) { this.someService2 = someService2; } public void doMyThing(){ someService.doSomething(); someService2.doSomething(); }}如果Bean只有一個構造器的話,我們可以直接省略@Autowired注解;若有多個構造器,需注解一個構造器用來注入如:
@Servicepublic class AnnotationOneInjectionService { private SomeService someService; public AnnotationOneInjectionService(SomeService someService) { this.someService = someService; } public void doMyThing(){ someService.doSomething(); }}- 配置注入
現在我們需要在Bean JavaConfigInjectService注入BeanAnotherService而使用Java配置的方式,JavaConfigInjectService定義如下:
public class JavaConfigInjectService { private AnotherService anotherService; public JavaConfigInjectService(AnotherService anotherService) { this.anotherService = anotherService; } public void doMyThing(){ anotherService.doAnotherThing(); }}前面我們已經將AnotherService通過@Bean注解成Bean了,我們只需在定義JavaConfigInjectService的Bean的方法參數里注入AnotherService的Bean即可:
@Beanpublic JavaConfigInjectService javaConfigInjectService(AnotherService anotherService){ return new JavaConfigInjectService(anotherService);}在同一個配置類里,我們還可以在新建JavaConfigInjectService的構造里直接注入創建SomeService2的Bean的方法:
@Beanpublic JavaConfigInjectService javaConfigInjectService(){ return new JavaConfigInjectService(anotherService());}- 混合注入
注解配置的Bean可以直接注入給使用Java配置的Bean,反之亦然。
- 注解Bean注入配置Bean:
- 配置Bean注入注解Bean:
被注入的Bean MixInjectionService2定義如下:
public class MixInjectionService2 { private SomeService someService; //是使用@Component注解配置的Bean public MixInjectionService2(SomeService someService) { this.someService = someService; } public void doMyThing(){ someService.doSomething(); }}在JavaConfig類里可以直接在參數注入:
@Beanpublic MixInjectionService2 mixInjectionService2(SomeService someService){ return new MixInjectionService2(someService);}2.3.2 @Primary2.3.2 @Primary
我們上面的例子都是通過Bean的名稱來自動注入的,當Bean的名稱不能滿足條件時候,容器會自動根據Bean的類型進行自動注入的,在全局只有一個類型的Bean的時候自動注入是沒有問題的,但是當全局有多個同類型的Bean的時候報required a single bean, but n were found,我們可以通過注解@Primary來注解需要優先使用的Bean,如我們有兩個Bean:
@Beanpublic AnotherService anotherService(){ return new AnotherService("wyf");}@Bean@Primarypublic AnotherService primaryAnotherService(){return new AnotherService("foo");}此時我們有兩個Bean,名稱分別為:anotherService和primaryAnotherService,我們在注入的地方不使用這個兩個名字,這時就會使用按照類型自動綁定:
@Componentpublic class UsePrimaryService { private AnotherService service; public UsePrimaryService(AnotherService service) { this.service = service; } public void doSomething(){ System.out.println("foo".equals(service.getPerson())); }}現在使用的service不符合按照名稱自動注入,而按照類型自動注入,因為primaryAnotherService注解了@Primary,所以使用primaryAnotherService這個Bean。
2.3.3 @Qualifier
上面的例子中我們使用UsePrimaryService注入的AnotherService的Bean只會是primaryAnotherService,我們可以使用@Qualifier直接指定需要使用哪個Bean,兩個Bean還是沿用上面的例子。
注入anotherService:
@Componentpublic class UseQualifierService { @Autowired @Qualifier("anotherService") //通過@Qualifier("anotherService")指定使用anotherService private AnotherService service; public void doSomething(){ System.out.println("wyf".equals(service.getPerson())); //2 }}注入primaryAnotherService:
@Componentpublic class UseQualifierService2 { private AnotherService service; public UseQualifierService2(@Qualifier("primaryAnotherService") AnotherService service) { this.service = service; } public void doSomething(){ System.out.println("foo".equals(service.getPerson())); }}2.4 運行檢驗 - CommandLineRunner
Spring Boot下可以注冊一個CommandLineRunner的Bean,這個Bean用來在容器啟動后執行一些專門的任務,在JavaConfig里:
@BeanCommandLineRunner configClr(AnnotationInjectionService annotationInjectionService, AnnotationOneInjectionService annotationOneInjectionService, AnnotationPropertyInjectionService annotationPropertyInjectionService, AnnotationSetterInjectionService annotationSetterInjectionService, JavaConfigInjectService javaConfigInjectService, MixInjectionService mixInjectionService, MixInjectionService2 mixInjectionService2, UsePrimaryService usePrimaryService, UseQualifierService useQualifierService, UseQualifierService2 useQualifierService2) { return args -> { System.out.println(args); annotationInjectionService.doMyThing(); annotationOneInjectionService.doMyThing(); annotationPropertyInjectionService.doMyThing(); annotationSetterInjectionService.doMyThing(); javaConfigInjectService.doMyThing(); mixInjectionService.doMyThing(); usePrimaryService.doSomething(); mixInjectionService2.doMyThing(); useQualifierService.doSomething(); useQualifierService2.doSomething(); };}CommandLineRunner有個姊妹接口叫做ApplicationRunner,唯一的區別是ApplicationRunner使用org.springframework.boot.DefaultApplicationArguments類型的參數。如:
@BeanApplicationRunner configAr(){ return args -> System.out.println(args); }CommandLineRunner的args是不定字符串(String... args),而ApplicationRunner的args是DefaultApplicationArguments類型的對象。
下一篇《SpringBoot實戰6-Spring基礎-Bean的Scope》
總結
以上是生活随笔為你收集整理的spring 5企业级开发实战pdf_SpringBoot实战5-Spring基础-配置与注入的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python爬虫搜特定内容的论文_Pyt
- 下一篇: python安装失败如何卸载干净_彻底卸