SpringBoot向容器注冊(cè)bean的方法詳解
簡(jiǎn)介
本文用示例介紹SpringBoot如何向容器注冊(cè)bean(即:將對(duì)象加入容器)。
法1:@Component
(@Controller/@Service/@Repository也可以,因?yàn)樗镞叞珸Component)
默認(rèn)是加載和Application類所在同一個(gè)目錄下的所有類,包括所有子目錄下的類。
當(dāng)啟動(dòng)類和@Component分開(kāi)時(shí),如果啟動(dòng)類在某個(gè)包下,需要在啟動(dòng)類中增加注解@ComponentScan,配置需要掃描的包名。例如:
@SpringBootApplication(scanBasePackages="com.test.chapter4")
此注解其實(shí)是@ComponentScan的basePackages,通過(guò)查看scanBasePackages即可得知。
@SpringBootApplication只會(huì)掃描@SpringBootApplication注解標(biāo)記類包下及其子包的類,將這些類納入到spring容器,只要類有@Component注解即可。
有的注解的定義中已加入@Component,所以這些注解也會(huì)被掃描到:@Controller,@Service,@Configuration,@Bean
@ComponentScan+@Configuration+@Component
DemoConfig在掃描路徑之內(nèi)
@Configuration
@ComponentScan(basePackages = { "com.example.demo.mybeans" })
public class DemoConfig {
}
MyBean1在com.example.demo.mybeans下
@Component
public class MyBean1{
}
法2:@Configuration+@Bean
使用場(chǎng)景:將沒(méi)有Component等注解的類導(dǎo)入。例如:第三方包里面的組件、將其他jar包中的類。
public class User {
//@Value("Tom")
public String username;
public User(String s) {
this.username = s;
}
}
@Configuration
public class ImportConfig {
@Bean
public User user(){
return new User("Lily");
}
}
@RestController
public class ImportDemoController {
@Autowired
private User user;
@RequestMapping("/importDemo")
public String demo() throws Exception {
String s = user.username;
return "ImportDemo@SpringBoot " + s;
}
}法3:@Import等
簡(jiǎn)介
@Import(要導(dǎo)入到容器中的組件);容器會(huì)自動(dòng)注冊(cè)這個(gè)組件,id默認(rèn)是全類名。(@Import是Spring的注解。)
ImportSelector:返回需要導(dǎo)入的組件的全類名數(shù)組;
ImportBeanDefinitionRegistrar:手動(dòng)注冊(cè)bean到容器中
@Import方式
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import({ImportDemoConfig.class})
public @interface EnableImportDemo {
}
public class ImportDemoConfig{
@Bean
public User user(){
return new User("Lily");
}
}
@EnableImportDemo
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@RestController
public class ImportDemoController {
@Autowired
private User user;
@RequestMapping("/importDemo")
public String demo() {
String s = user.getName();
return "user.getName():" + s;
}
}ImportSelector方式
//自定義邏輯返回需要導(dǎo)入的組件
public class MyImportSelector implements ImportSelector {
//返回值,就是到導(dǎo)入到容器中的組件全類名
//AnnotationMetadata:當(dāng)前標(biāo)注@Import注解的類的所有注解信息
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
//當(dāng)前類的所有注解
Set<String> annotationTypes = importingClassMetadata.getAnnotationTypes();
System.out.println("當(dāng)前配置類的注解信息:"+annotationTypes);
//注意不能返回null,不然會(huì)報(bào)NullPointException
return new String[]{"com.paopaoedu.springboot.bean.user01","com.paopaoedu.springboot.bean.user02"};
}
}
public class User01 {
public String username;
public User01() {
System.out.println("user01...constructor");
}
}
public class User02 {
public String username;
public User02() {
System.out.println("user02...constructor");
}
}
@Configuration
@Import({ImportDemo.class, MyImportSelector.class})
public class ImportConfig {
@Bean
public User user(){
return new User("Lily");
}
}
@RestController
public class ImportDemoController {
@Autowired
private User user;
@Autowired
private ImportDemo importDemo;
@Autowired
private User01 user01;
@RequestMapping("/importDemo")
public String demo() throws Exception {
importDemo.doSomething();
user01.username = "user01";
String s = user.username;
String s1 = user01.username;
return "ImportDemo@SpringBoot " + s + " " + s1;
}
}ImportBeanDefinitionRegistrar方式
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/**
* AnnotationMetadata:當(dāng)前類的注解信息
* BeanDefinitionRegistry:BeanDefinition注冊(cè)類;
* 把所有需要添加到容器中的bean;調(diào)用
* BeanDefinitionRegistry.registerBeanDefinition手工注冊(cè)進(jìn)來(lái)
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
boolean definition = registry.containsBeanDefinition("com.paopaoedu.springboot.bean.User01");
boolean definition2 = registry.containsBeanDefinition("com.paopaoedu.springboot.bean.User02");
if(definition && definition2){
//指定Bean定義信息作用域都可以在這里定義;(Bean的類型,Bean。。。)
RootBeanDefinition beanDefinition = new RootBeanDefinition(User03.class);
//注冊(cè)一個(gè)Bean,指定bean名
registry.registerBeanDefinition("User03", beanDefinition);
}
}
}public class User03 {
public String username;
public User03() {
System.out.println("user03...constructor");
}
}使用上和前面的類似就不舉例了。
法4:FactoryBean
默認(rèn)獲取到的是工廠bean調(diào)用getObject創(chuàng)建的對(duì)象。
要獲取工廠Bean本身,我們需要給id前面加一個(gè)&。例如:&xxxFactoryBean 注意類名是X,這里就是小寫的x
public class UserFactoryBean implements FactoryBean<User04> {
@Override
public User04 getObject() throws Exception {
// TODO Auto-generated method stub
System.out.println("UserFactoryBean...getObject...");
return new User04("User04");
}
@Override
public Class<?> getObjectType() {
// TODO Auto-generated method stub
return User04.class;
}
//是否單例?
//true:這個(gè)bean是單實(shí)例,在容器中保存一份
//false:多實(shí)例,每次獲取都會(huì)創(chuàng)建一個(gè)新的bean;
@Override
public boolean isSingleton() {
return true;
}
}
public class User04 {
public String username;
public User04(String s) {
String nowtime= DateUtil.now();
username=s+" "+nowtime;
}
}
@Configuration
@Import({ImportDemo.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class ImportConfig {
// 要獲取工廠Bean本身,需要給id前面加一個(gè)&,&userFactoryBean
@Bean
public UserFactoryBean userFactoryBean(){
return new UserFactoryBean();
}
@Bean
public User user(){
return new User("Lily");
}
}
@RestController
public class ImportDemoController {
@Autowired
private User user;
@Autowired
private ImportDemo importDemo;
@Autowired
private User01 user01;
@Autowired
private UserFactoryBean userFactoryBean;
@RequestMapping("/importDemo")
public String demo() throws Exception {
importDemo.doSomething();
user01.username = "user01";
String s = user.username;
String s1 = user01.username;
String s4 = userFactoryBean.getObject().username;
return "ImportDemo@SpringBoot " + s + " " + s1 + " " + s4;
}
}
@SpringBootApplication
public class SpringBootLearningApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootLearningApplication.class, args);
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext("com.paopaoedu.springboot.config");
ImportDemo importDemo = context.getBean(ImportDemo.class);
importDemo.doSomething();
printClassName(context);
Object bean1 = context.getBean("userFactoryBean");
Object bean2 = context.getBean("userFactoryBean");
System.out.println(bean1 == bean2);
}
private static void printClassName(AnnotationConfigApplicationContext annotationConfigApplicationContext){
String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
for (int i = 0; i < beanDefinitionNames.length; i++) {
System.out.println("匹配的類"+beanDefinitionNames[i]);
}
}
}測(cè)試結(jié)果


以上就是SpringBoot向容器注冊(cè)bean的方法詳解的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot注冊(cè)bean的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringCloud實(shí)戰(zhàn)小貼士之Zuul的路徑匹配
這篇文章主要介紹了SpringCloud實(shí)戰(zhàn)小貼士之Zuul的路徑匹配,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10
Java實(shí)現(xiàn)復(fù)制文件并命名的超簡(jiǎn)潔寫法
這篇文章主要介紹了Java實(shí)現(xiàn)復(fù)制文件并命名的超簡(jiǎn)潔寫法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
Spring Data Jpa Mysql使用utf8mb4編碼的示例代碼
這篇文章主要介紹了Spring Data Jpa Mysql使用utf8mb4編碼的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-11-11
Java數(shù)據(jù)結(jié)構(gòu)之鏈表詳解
本篇文章我們將講解一種新型的數(shù)據(jù)結(jié)構(gòu)—鏈表,鏈表是一種使用廣泛的通用數(shù)據(jù)結(jié)構(gòu),它可以用來(lái)作為實(shí)現(xiàn)棧,隊(duì)列等數(shù)據(jù)結(jié)構(gòu)的基礎(chǔ).文中有非常詳細(xì)的介紹,需要的朋友可以參考下2021-05-05
Java微信小程序oss圖片上傳的實(shí)現(xiàn)方法
這篇文章主要介紹了Java微信小程序oss圖片上傳的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12
SpringBoot的ConfigurationProperties或Value注解無(wú)效問(wèn)題及解決
在SpringBoot項(xiàng)目開(kāi)發(fā)中,全局靜態(tài)配置類讀取application.yml或application.properties文件時(shí),可能會(huì)遇到配置值始終為null的問(wèn)題,這通常是因?yàn)樵趧?chuàng)建靜態(tài)屬性后,IDE自動(dòng)生成的Get/Set方法包含了static關(guān)鍵字2024-11-11
Java實(shí)現(xiàn)XML文件學(xué)生通訊錄
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)XML文件學(xué)生通訊錄,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02
Geotools實(shí)現(xiàn)shape文件的寫入功能
Geotools作為開(kāi)源的Java?GIS三方庫(kù),已經(jīng)成為GIS服務(wù)器端的主流開(kāi)源庫(kù),其功能非常強(qiáng)大,涉及到GIS業(yè)務(wù)的方方面面,其中就包括GIS數(shù)據(jù)的讀寫,今天小編就借助Geotools來(lái)實(shí)現(xiàn)shape數(shù)據(jù)的寫入,需要的朋友可以參考下2023-08-08

