SpringBoot Bean被加載時進行控制
序章
簡介:bean的加載控制指根據(jù)特定情況對bean進行選擇性加載以達到適用項目的目標。
根據(jù)之前對bean加載的八種方式,其中后面四種是可以對bean被加載時進行控制。
我拿第六種來舉個例子。
之前也舉過例子,但是實際開發(fā)呢,一般不會那么使用。
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;
}
}通過查看某個類是否存在來控制是否加載目標類。
這個類我是不存在的。
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);
}
}
}
所以我是沒有加載這個bean的,還是老話,前面的那些暫時不看。
加載控制@Conditional派生注解
到了這里,你的spring項目就該換成springboot項目了,pom.xml中添加坐標,我就不多說了,這就是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);
}
}
}
有貓,有狗,有老鼠,只不過我給他們都起了名字,你們很容易就會看出來。
現(xiàn)在我要對貓這個bean在創(chuàng)建時加一控制。
控制后
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) //要加載貓,必須要有老鼠這個bean
@ConditionalOnBean(name = "zhizhi") //而且這個老鼠bean的名字必須是“zhizhi”
@ConditionalOnMissingClass("yi.beans.Dog") //但是不能有狗,貓捉老鼠不想有狗
@ConditionalOnNotWebApplication //環(huán)境必須為非Web環(huán)境
@Component("miao") //貓的bean叫“miao”
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Cat {
String shout;
}這里我加了幾個常見的派生注解,其他的代碼都是不用變的,我的bean里賣雖然有一個叫做“zhizhi”的老鼠,但是有狗,所以貓是加載不出來的。

其中的
@ConditionalOnClass
@ConditionalOnBean
這兩個注解非常相似,一般就用上面那個控制類的字節(jié)碼或者路徑。下面那個獲取bean的名字,搭配使用就好了。
bean依賴的屬性配置
先定義兩個最基礎的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)在我把配置注解一部分,我們再來看運行結果。
cartoon:
cat:
# name: "圖多蓋洛"
age: 5
mouse:
# name: "泰菲"
age: 1

可以看到,沒有寫的屬性使用的就是默認屬性,也就是自動配置的思想,只有在調用的時候才會生成bean,默認的bean也不會在項目加載時就添加,這樣壓力會很大。如果我們沒有使用某個第三方的bean,我們的項目啟動時也并不會加載默認的bean。
到此這篇關于SpringBoot Bean被加載時進行控制的文章就介紹到這了,更多相關SpringBoot Bean加載控制內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringBoot編譯target目錄下沒有resource下的文件踩坑記錄
這篇文章主要介紹了SpringBoot編譯target目錄下沒有resource下的文件踩坑記錄,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-08-08
SpringBoot對接AWS?S3實現(xiàn)上傳和查詢
AWS?S3是亞馬遜提供的一種對象存儲服務,旨在提供可擴展、高可用性和安全的數(shù)據(jù)存儲解決方案,本文我們就來看看SpringBoot如何對接AWS?S3實現(xiàn)上傳和查詢吧2025-02-02
Java編程數(shù)組中最大子矩陣簡便解法實現(xiàn)代碼
這篇文章主要介紹了Java編程數(shù)組中最大子矩陣簡便解法實現(xiàn)代碼,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下2018-01-01
Mybatis?mysql模糊查詢方式(CONCAT多個字段)及bug
這篇文章主要介紹了Mybatis?mysql模糊查詢方式(CONCAT多個字段)及bug,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01
SpringCloud maven-assembly-plugin 多級目錄打包的實現(xiàn)
本文主要介紹了SpringCloud maven-assembly-plugin 多級目錄打包的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-10-10
Java8時間api之LocalDate/LocalDateTime的用法詳解
在項目中,時間的使用必不可少,而java8之前的時間api?Date和Calander等在使用上存在著很多問題,于是,jdk1.8引進了新的時間api-LocalDateTime,本文就來講講它的具體使用吧2023-05-05

