SpringBoot Bean被加載時(shí)進(jìn)行控制
序章
簡(jiǎn)介:bean的加載控制指根據(jù)特定情況對(duì)bean進(jìn)行選擇性加載以達(dá)到適用項(xiàng)目的目標(biāo)。
根據(jù)之前對(duì)bean加載的八種方式,其中后面四種是可以對(duì)bean被加載時(shí)進(jìn)行控制。
我拿第六種來舉個(gè)例子。
之前也舉過例子,但是實(shí)際開發(fā)呢,一般不會(huì)那么使用。
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
try {
Class<?> name = Class.forName("yi.beans.kun");
if (name!=null){
return new String[]{"yi.beans.Cat"};
}
}catch (ClassNotFoundException e){
return new String[0];
}
return null;
}
}通過查看某個(gè)類是否存在來控制是否加載目標(biāo)類。
這個(gè)類我是不存在的。
import org.springframework.context.annotation.Import;
import yi.beans.MyImportSelector;
@Import(MyImportSelector.class)
public class AConfig {
}import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import yi.config.AConfig;
public class App3 {
public static void main(String[] args) {
ApplicationContext context=new AnnotationConfigApplicationContext(AConfig.class);
String[] names = context.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
}
}
所以我是沒有加載這個(gè)bean的,還是老話,前面的那些暫時(shí)不看。
加載控制@Conditional派生注解
到了這里,你的spring項(xiàng)目就該換成springboot項(xiàng)目了,pom.xml中添加坐標(biāo),我就不多說了,這就是springboot的注解,源代碼中大量使用。
這是我未加控制前的代碼
import org.springframework.context.annotation.ComponentScan;
@ComponentScan("yi.beans")
public class AConfig {
}import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import yi.config.AConfig;
public class App3 {
public static void main(String[] args) {
ApplicationContext context=new AnnotationConfigApplicationContext(AConfig.class);
String[] names = context.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
}
}
有貓,有狗,有老鼠,只不過我給他們都起了名字,你們很容易就會(huì)看出來。
現(xiàn)在我要對(duì)貓這個(gè)bean在創(chuàng)建時(shí)加一控制。
控制后
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWebApplication;
import org.springframework.stereotype.Component;
@ConditionalOnClass(Mouse.class) //要加載貓,必須要有老鼠這個(gè)bean
@ConditionalOnBean(name = "zhizhi") //而且這個(gè)老鼠bean的名字必須是“zhizhi”
@ConditionalOnMissingClass("yi.beans.Dog") //但是不能有狗,貓捉老鼠不想有狗
@ConditionalOnNotWebApplication //環(huán)境必須為非Web環(huán)境
@Component("miao") //貓的bean叫“miao”
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Cat {
String shout;
}這里我加了幾個(gè)常見的派生注解,其他的代碼都是不用變的,我的bean里賣雖然有一個(gè)叫做“zhizhi”的老鼠,但是有狗,所以貓是加載不出來的。

其中的
@ConditionalOnClass
@ConditionalOnBean
這兩個(gè)注解非常相似,一般就用上面那個(gè)控制類的字節(jié)碼或者路徑。下面那個(gè)獲取bean的名字,搭配使用就好了。
bean依賴的屬性配置
先定義兩個(gè)最基礎(chǔ)的bean
import lombok.Data;
@Data
public class Mouse {
private String name;
private int age;
}import lombok.Data;
@Data
public class Cat {
private String name;
private int age;
}cartoon:
cat:
name: "圖多蓋洛"
age: 5
mouse:
name: "泰菲"
age: 1
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
@Data
@ConfigurationProperties(prefix = "cartoon")
public class CartoonProperties {
private Cat cat;
private Mouse mouse;
}import lombok.Data;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
@Data
@Component
@EnableConfigurationProperties(CartoonProperties.class)
public class CartoonCatAndMouse {
private Cat cat;
private Mouse mouse;
private CartoonProperties cartoonProperties;
public CartoonCatAndMouse(CartoonProperties cartoonProperties){
this.cartoonProperties=cartoonProperties;
this.cat=new Cat();
this.cat.setName(cartoonProperties.getCat()!=null&& StringUtils.hasText(cartoonProperties.getCat().getName())?
cartoonProperties.getCat().getName():"Tom");
this.cat.setAge(cartoonProperties.getCat()!=null&& cartoonProperties.getCat().getAge()!=0?
cartoonProperties.getCat().getAge():6);
this.mouse=new Mouse();
this.mouse.setName(cartoonProperties.getMouse()!=null&&StringUtils.hasText(cartoonProperties.getMouse().getName())?
cartoonProperties.getMouse().getName():"Jerry");
this.mouse.setAge(cartoonProperties.getMouse()!=null && cartoonProperties.getMouse().getAge()!=0?
cartoonProperties.getMouse().getAge():2);
}
public void play() {
System.out.println(cat.getAge()+"歲的"+cat.getName()+"和"+mouse.getAge()+"歲的"+mouse.getName()+"打起來了");
}
}import com.yi.bean.CartoonCatAndMouse;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class SpringbootBean2ApplicationTests {
@Autowired
private CartoonCatAndMouse cartoonCatAndMouse;
@Test
void contextLoads() {
cartoonCatAndMouse.play();
}
}
可以看到加載的就是我們自己寫的配置,現(xiàn)在我把配置注解一部分,我們?cè)賮砜催\(yùn)行結(jié)果。
cartoon:
cat:
# name: "圖多蓋洛"
age: 5
mouse:
# name: "泰菲"
age: 1

可以看到,沒有寫的屬性使用的就是默認(rèn)屬性,也就是自動(dòng)配置的思想,只有在調(diào)用的時(shí)候才會(huì)生成bean,默認(rèn)的bean也不會(huì)在項(xiàng)目加載時(shí)就添加,這樣壓力會(huì)很大。如果我們沒有使用某個(gè)第三方的bean,我們的項(xiàng)目啟動(dòng)時(shí)也并不會(huì)加載默認(rèn)的bean。
到此這篇關(guān)于SpringBoot Bean被加載時(shí)進(jìn)行控制的文章就介紹到這了,更多相關(guān)SpringBoot Bean加載控制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java通過索引值實(shí)現(xiàn)約瑟夫環(huán)算法
這篇文章主要介紹了Java通過索引值實(shí)現(xiàn)約瑟夫環(huán),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05
SpringBoot編譯target目錄下沒有resource下的文件踩坑記錄
這篇文章主要介紹了SpringBoot編譯target目錄下沒有resource下的文件踩坑記錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08
SpringBoot對(duì)接AWS?S3實(shí)現(xiàn)上傳和查詢
AWS?S3是亞馬遜提供的一種對(duì)象存儲(chǔ)服務(wù),旨在提供可擴(kuò)展、高可用性和安全的數(shù)據(jù)存儲(chǔ)解決方案,本文我們就來看看SpringBoot如何對(duì)接AWS?S3實(shí)現(xiàn)上傳和查詢吧2025-02-02
Java 圖片與byte數(shù)組互相轉(zhuǎn)換實(shí)例
下面小編就為大家?guī)硪黄狫ava 圖片與byte數(shù)組互相轉(zhuǎn)換實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-02-02
Java編程數(shù)組中最大子矩陣簡(jiǎn)便解法實(shí)現(xiàn)代碼
這篇文章主要介紹了Java編程數(shù)組中最大子矩陣簡(jiǎn)便解法實(shí)現(xiàn)代碼,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01
Mybatis?mysql模糊查詢方式(CONCAT多個(gè)字段)及bug
這篇文章主要介紹了Mybatis?mysql模糊查詢方式(CONCAT多個(gè)字段)及bug,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01
spring通過導(dǎo)入jar包和配置xml文件啟動(dòng)的步驟詳解
這篇文章主要介紹了spring通過導(dǎo)入jar包和配置xml文件啟動(dòng),本文分步驟通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08
SpringCloud maven-assembly-plugin 多級(jí)目錄打包的實(shí)現(xiàn)
本文主要介紹了SpringCloud maven-assembly-plugin 多級(jí)目錄打包的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10
Java8時(shí)間api之LocalDate/LocalDateTime的用法詳解
在項(xiàng)目中,時(shí)間的使用必不可少,而java8之前的時(shí)間api?Date和Calander等在使用上存在著很多問題,于是,jdk1.8引進(jìn)了新的時(shí)間api-LocalDateTime,本文就來講講它的具體使用吧2023-05-05

