Spring容器注入bean的五種方法逐個(gè)解析
前言
我們?cè)陧?xiàng)目開發(fā)中都用到Spring,知道對(duì)象是交由Spring去管理。那么將一個(gè)對(duì)象加入到Spring容器中,有幾種方法呢,我們來(lái)總結(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用來(lái)聲明一個(gè)配置類,如果它的方法被@Bean修飾,那么該方法返回的對(duì)象也會(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方法返回的對(duì)象也能注入到容器中
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方法返回的對(duì)象也會(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ù))加載完成后,再對(duì)它進(jìn)行后置處理。所以可以在此調(diào)整BeanDefinition,從而把對(duì)應(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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java實(shí)現(xiàn)圖片與二進(jìn)制的互相轉(zhuǎn)換
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)圖片與二進(jìn)制的互相轉(zhuǎn)換,將圖片轉(zhuǎn)二進(jìn)制再將二進(jìn)制轉(zhuǎn)成圖片,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03
java去除中文括號(hào)小括號(hào),或者英文括號(hào)的實(shí)例代碼
這篇文章主要介紹了java去除中文括號(hào)小括號(hào),或者英文括號(hào)的實(shí)例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧2020-09-09
IDEA個(gè)性化設(shè)置注釋模板詳細(xì)講解版
IDEA自帶的注釋模板不是太好用,我本人到網(wǎng)上搜集了很多資料系統(tǒng)的整理了一下制作了一份比較完整的模板來(lái)分享給大家,下面這篇文章主要給大家介紹了IDEA個(gè)性化設(shè)置注釋模板的相關(guān)資料,需要的朋友可以參考下2024-01-01
學(xué)習(xí)C語(yǔ)言對(duì)后期java有幫助嗎
在本篇文章里小編給大家整理的是一篇關(guān)于學(xué)習(xí)C語(yǔ)言對(duì)后期java有幫助嗎的基礎(chǔ)文章,有興趣的朋友們可以參考下。2020-11-11
SpringBoot讀取properties或者application.yml配置文件中的數(shù)據(jù)
這篇文章主要介紹了SpringBoot讀取properties或者application.yml配置文件中的數(shù)據(jù),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
解析SpringBoot中@Autowire注解的實(shí)現(xiàn)原理
在開發(fā)Java項(xiàng)目時(shí),依賴注入是一種常見的實(shí)現(xiàn)方式,SpringBoot框架通過@Autowired注解來(lái)實(shí)現(xiàn)依賴注入的功能,本文將介紹SpringBoot中 Autowired注解實(shí)現(xiàn)的原理2023-06-06

