SpringBoot中注冊Bean的方式總結(jié)
@ComponentScan + @Componet相關(guān)注解
@Componet相關(guān)注解有@Configuration、@Controller、@Service、@Repository,配合@ComponentScan就能被掃描注冊到Spring容器中。
定義我們需要注冊的類
@Configuration public class ForlanConfig { @Bean public ForlanBean forlanBean1(){ return new ForlanBean(); } } @Component // @Controller // @Service // @Repository public class ForlanComponent { @Bean public ForlanBean forlanBean2(){ return new ForlanBean(); } } public class ForlanBean { }
驗(yàn)證如下:
public static void main(String[] args) { ConfigurableApplicationContext applicationContext = SpringApplication.run(Application.class, args); System.out.println(applicationContext.getBean("forlanConfig")); System.out.println(applicationContext.getBean("forlanComponent")); } // 輸出如下: cn.forlan.ForlanConfig$$EnhancerBySpringCGLIB$$e43dabb2@1305c126 cn.forlan.ForlanComponent@43af351a
@Bean
前面已經(jīng)定義好需要注冊的類,直接驗(yàn)證即可
驗(yàn)證如下:
public static void main(String[] args) { ConfigurableApplicationContext applicationContext = SpringApplication.run(Application.class, args); System.out.println(applicationContext.getBean("forlanBean1")); System.out.println(applicationContext.getBean("forlanBean2")); } // 輸出如下: cn.forlan.ForlanBean@64279ab cn.forlan.ForlanBean@6650a6c
@Import
它可以導(dǎo)入的類有:Component, Configuration, ImportSelector, ImportBeanDefinitionRegistrar, ImportResource
定義我們需要注冊的類
public class CaffeineForlanCache { } public class RedisForlanCache { } public class ForlanCustomize { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
實(shí)現(xiàn)ImportSelector
public class ForlanImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(EnableForlanCache.class.getName()); //通過 不同type注入不同的緩存到容器中 CacheType cacheType = (CacheType) annotationAttributes.get("cacheType"); if(cacheType.equals(CacheType.CAFFEINE)){ return new String[]{CaffeineForlanCache.class.getName()}; }else{ return new String[]{RedisForlanCache.class.getName()}; } } }
實(shí)現(xiàn)ImportBeanDefinitionRegistrar
public class ForlanBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(ForlanCustomize.class) .addPropertyValue("name", "forlan").getBeanDefinition(); registry.registerBeanDefinition("forlanCustomize", beanDefinition); } }
定義注解導(dǎo)入
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import({ForlanImportSelector.class, ForlanBeanDefinitionRegistrar.class}) public @interface EnableForlanCache { CacheType cacheType() default CacheType.REDIS; }
驗(yàn)證如下:
@EnableForlanCache(cacheType = CacheType.CAFFEINE) public class Application { public static void main(String[] args) { ConfigurableApplicationContext applicationContext = SpringApplication.run(Application.class, args); System.out.println(applicationContext.getBean("forlanBean1")); System.out.println(applicationContext.getBean("forlanBean2")); } } // 輸出如下: cn.forlan.ForlanCustomize@245cb8df cn.forlan.CaffeineForlanCache@578c3fd9 Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'cn.forlan.RedisForlanCache' available
spring.factories
定義我們需要注冊的類
public class ForlanAutoConfiguration { }
在resources\META-INF下新建spring.factories,填寫內(nèi)容,SpringBoot在啟動時,就會自動注入
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ cn.forlan.ForlanAutoConfiguration
驗(yàn)證如下:
public static void main(String[] args) { ConfigurableApplicationContext applicationContext = SpringApplication.run(Application.class, args); System.out.println(applicationContext.getBean(ForlanAutoConfiguration.class)); System.out.println(applicationContext.getBean("cn.forlan.ForlanAutoConfiguration")); } // 輸出如下: cn.forlan.ForlanAutoConfiguration@19d53ab4 cn.forlan.ForlanAutoConfiguration@19d53ab4
注:這種方式的注入的BeanName為路徑+類名
總結(jié)
總的來說,一共有如下幾種方式可以注冊bean:
- @ComponentScan + @Componet相關(guān)注解
- 使用@Bean注解
- 使用@Import注解
- spring.factories
@Configuration和@Component的主要區(qū)別?
使用場景:@Configuration主要用于定義配置類,其中包含了Bean的定義和配置;而@Component適用于任何需要被Spring管理的類。
功能:@Configuration主要用于配置類的定義和初始化Bean;而@Component主要用于組件的自動掃描和注冊。
@Bean是不是必須和@Configuration一起使用?
不是的,盡管@Bean注解常常出現(xiàn)在帶有@Configuration注解的配置類中,用于定義和初始化Spring容器中的Bean,但它也可以單獨(dú)使用。@Bean注解的主要作用是告訴Spring框架,被該注解標(biāo)注的方法將返回一個對象,這個對象需要被注冊到Spring容器中。在非配置類中使用@Bean注解,只需要確保該方法能夠被Spring掃描到即可。
@Import導(dǎo)入配置類有意義?
總結(jié)來說,@Import導(dǎo)入的類本身不是Bean,而是用于擴(kuò)展Spring容器配置的工具。它可以定義或注冊其他的Bean,但你不能直接通過applicationContext.getBean()獲取這些導(dǎo)入類的實(shí)例。相反,你應(yīng)該獲取它們定義或注冊的Bean的實(shí)例。它的主要價值在于動態(tài)注入Bean。
出現(xiàn)異常:java.lang.NoClassDefFoundError: Could not initialize class org.springframework.beans.factory.BeanDefinitionStoreException
原因是這個類寫的有問題,F(xiàn)orlanImportSelector根本就沒有初始化,不是是當(dāng)前類
以上就是SpringBoot中注冊Bean的方式總結(jié)的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot注冊Bean的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
手把手教你如何利用SpringBoot實(shí)現(xiàn)審核功能
審核功能經(jīng)過幾個小時的奮戰(zhàn)終于完成了,現(xiàn)在我就與廣大網(wǎng)友分享我的成果,這篇文章主要給大家介紹了關(guān)于如何利用SpringBoot實(shí)現(xiàn)審核功能的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-05-05restTemplate發(fā)送get與post請求并且?guī)?shù)問題
這篇文章主要介紹了restTemplate發(fā)送get與post請求并且?guī)?shù)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07Java編程小實(shí)例—數(shù)字時鐘的實(shí)現(xiàn)代碼示例
正所謂拳不離手曲不離口,java學(xué)習(xí)的過程中,練習(xí)還是要多一點(diǎn)比較好。接下來分享給大家一個Java編程的小實(shí)例,供朋友們參考。2017-10-10Java基于Servlet和JSP實(shí)現(xiàn)登錄功能
在 Web 開發(fā)中,用戶登錄功能是非常常見的模塊之一,本文將通過使用 Java Servlet 和 JSP 實(shí)現(xiàn)一個簡單的用戶登錄功能,展示如何創(chuàng)建登錄頁面、處理用戶登錄請求,并使用數(shù)據(jù)庫驗(yàn)證用戶信息,需要的朋友可以參考下2024-11-11Java實(shí)現(xiàn)的簡單網(wǎng)頁截屏功能示例
這篇文章主要介紹了Java實(shí)現(xiàn)的簡單網(wǎng)頁截屏功能,涉及java網(wǎng)頁打開及屏幕截圖功能相關(guān)操作技巧,需要的朋友可以參考下2017-12-12Java設(shè)計模式之裝飾模式(Decorator模式)介紹
這篇文章主要介紹了Java設(shè)計模式之裝飾模式(Decorator模式)介紹,本文講解了為什么使用Decorator、如何使用裝飾模式、Jive中的Decorator實(shí)現(xiàn)等內(nèi)容,需要的朋友可以參考下2015-03-03Java實(shí)現(xiàn)數(shù)字金額轉(zhuǎn)化為英文金額功能
在處理財務(wù)數(shù)據(jù)時,有時需要將數(shù)字形式的金額轉(zhuǎn)換成英文描述的形式,比如在生成正式文件或發(fā)票時,本文將介紹如何使用Java實(shí)現(xiàn)這一功能,需要的朋友可以參考下2025-03-03