Spring容器注入bean的五種方法逐個(gè)解析
前言
我們在項(xiàng)目開發(fā)中都用到Spring,知道對象是交由Spring去管理。那么將一個(gè)對象加入到Spring容器中,有幾種方法呢,我們來總結(jié)一下。
@ComponentScan+@Component
@ComponentScan可以放在啟動(dòng)類上,指定要掃描的包路徑;該包路徑下被@Component修飾的類,都會(huì)被注入到Spring容器中。
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; @ComponentScan(basePackages = "com.gs.beanRegister") public class BootStrap { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BootStrap.class); A bean = context.getBean(A.class); bean.say(); } }
com.gs.beanRegister包下:
import org.springframework.stereotype.Component; @Component public class A { public void say() { System.out.println("這是a"); } }
注:在SpringBoot中,由于其自動(dòng)裝配的特性,所以@ComponentScan可以不加,只要@Component修飾的類和啟動(dòng)類在同一包下或者在啟動(dòng)類所在包的子包下。
@Configuration+@Bean
@Configuration用來聲明一個(gè)配置類,如果它的方法被@Bean修飾,那么該方法返回的對象也會(huì)被注入到Spring容器中。
代碼方面,BootStrap 類不動(dòng),A類的@Component去掉,com.gs.beanRegister包下建個(gè)配置類:
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Bean; @Configuration public class MyConfiguration { @Bean public A a() { return new A(); } }
通過@Import注解
這個(gè)注解可能平時(shí)大家接觸得不多,它有好幾種使用方式。
1.直接導(dǎo)入類的class
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.AnnotationConfigApplicationContext; @Import(A.class) public class BootStrap { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BootStrap.class); A bean = context.getBean(A.class); //B bean = context.getBean(B.class); bean.say(); } }
A類不用添加任何注解:
public class A { public void say() { System.out.println("這是a"); } }
2.導(dǎo)入配置類
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Import; @Import(MyConfiguration.class) public class BootStrap { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BootStrap.class); A bean = context.getBean(A.class); bean.say(); } }
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; // 使用@Import導(dǎo)入配置類時(shí),@Configuration可以不加 //@Configuration public class MyConfiguration { @Bean public A a() { return new A(); } }
3.導(dǎo)入ImportSelector的實(shí)現(xiàn)類
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Import; @Import(MyImportSelector.class) public class BootStrap { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BootStrap.class); A bean = context.getBean(A.class); bean.say(); } }
import org.springframework.context.annotation.ImportSelector; import org.springframework.core.type.AnnotationMetadata; public class MyImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata metadata) { // 返回要注入的bean的全路徑,A類不用任何注解修飾 // SpringBoot的自動(dòng)裝配,就用到了這種方式: // 返回配置類的全路徑,配置類的@Bean方法返回的對象也能注入到容器中 return new String[] { A.class.getName() }; } }
4.導(dǎo)入ImportBeanDefinitionRegistrar的實(shí)現(xiàn)類
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Import; @Import(MyImportBeanDefinitionRegistrar.class) public class BootStrap { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BootStrap.class); A bean = context.getBean(A.class); bean.say(); } }
import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.core.type.AnnotationMetadata; public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) { // 構(gòu)建bean的元數(shù)據(jù),A類不用任何注解修飾 // spring-mybatis掃描mapper接口,生成代理類,就是用的這種方式 BeanDefinition definition = new RootBeanDefinition(A.class); registry.registerBeanDefinition("a", definition); } }
借助FactoryBean接口
實(shí)現(xiàn)FactoryBean接口的類,除了本身會(huì)被注入外,getObject方法返回的對象也會(huì)被注入到Spring容器中。
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Import; @Import(MyFactoryBean.class) public class BootStrap { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BootStrap.class); A bean = context.getBean(A.class); bean.say(); } }
import org.springframework.beans.factory.FactoryBean; public class MyFactoryBean implements FactoryBean { @Override public Object getObject() throws Exception { return new A(); } @Override public Class<?> getObjectType() { return A.class; } }
借助BeanDefinitionRegistryPostProcessor接口
在Spring容器啟動(dòng)時(shí),會(huì)調(diào)用該接口的postProcessBeanDefinitionRegistry方法,大概意思是等BeanDefinition(上面提到的bean的元數(shù)據(jù))加載完成后,再對它進(jìn)行后置處理。所以可以在此調(diào)整BeanDefinition,從而把對應(yīng)的bean注入。
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class BootStrap { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); BeanDefinitionRegistryPostProcessor postProcessor = new MyBeanDefinitionRegistryPostProcessor(); context.addBeanFactoryPostProcessor(postProcessor); context.refresh(); A a = context.getBean(A.class); a.say(); } }
import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; import org.springframework.beans.factory.support.RootBeanDefinition; public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { BeanDefinition definition = new RootBeanDefinition(A.class); registry.registerBeanDefinition("a", definition); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { } }
到此這篇關(guān)于Spring容器注入bean的五種方法逐個(gè)解析的文章就介紹到這了,更多相關(guān)Spring注入bean內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MyBatis如何調(diào)用存儲(chǔ)過程與存儲(chǔ)函數(shù)
這篇文章主要介紹了MyBatis如何調(diào)用存儲(chǔ)過程與存儲(chǔ)函數(shù),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11SpringCloud-Gateway轉(zhuǎn)發(fā)WebSocket失敗問題及解決
這篇文章主要介紹了SpringCloud-Gateway轉(zhuǎn)發(fā)WebSocket失敗問題及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09SpringBoot中MapStruct實(shí)現(xiàn)優(yōu)雅的數(shù)據(jù)復(fù)制
本文主要介紹了SpringBoot中MapStruct實(shí)現(xiàn)優(yōu)雅的數(shù)據(jù)復(fù)制,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-08-08SpringBoot詳解如何進(jìn)行整合Druid數(shù)據(jù)源
Druid是阿里開發(fā)的一款開源的數(shù)據(jù)源,被很多人認(rèn)為是Java語言中最好的數(shù)據(jù)庫連接池,本文主要介紹了SpringBoot整合Druid數(shù)據(jù)源的方法實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06SpringBoot實(shí)現(xiàn)文件上傳與下載功能的示例代碼
文件上傳與下載是Web應(yīng)用開發(fā)中常用的功能之一。接下來我們將討論如何在Spring?Boot的Web應(yīng)用開發(fā)中,如何實(shí)現(xiàn)文件的上傳與下載,感興趣的可以了解一下2022-06-06