Spring深入分析容器接口作用
1.容器接口有哪些
在Spring中,容器接口有BeanFactory 接口和ApplicationContext 接口
其繼承關(guān)系如下(Ctrl + alt + u)

由這個(gè)繼承關(guān)系圖可以看出,ApplicationContext 接口是 BeanFactory 的子接口。它擴(kuò)展了 BeanFactory 接口的功能
而B(niǎo)eanFactory 才是 Spring 的核心容器, 主要的 ApplicationContext 實(shí)現(xiàn)都【組合】了它的功能
那么在哪里可以看見(jiàn)ApplicationContext 類呢?
就在SpringBoot的啟動(dòng)類中可以看見(jiàn)
@SpringBootApplication
@MapperScan("com.lingnan.mapper")
public class TestSpringbootApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(TestSpringbootApplication.class, args);
}
}SpringApplication.run()方法的返回值,則是ApplicationContext 的子類ConfigurableApplicationContext,也就是Spring容器
使用debug模式,可以清晰看見(jiàn)ApplicationContext 里面有BeanFactory ,并且BeanFactory 有很多單例

2.BeanFactory能干嘛
使用快捷鍵Ctrl + n查找BeanFactory,然后使用Ctrl + F12即可查看BeanFactory的方法

可以看到,BeanFactory接口的方法看起來(lái)并不多,只有g(shù)etBean
實(shí)際上控制反轉(zhuǎn)、基本的依賴注入、直至 Bean 的生命周期的各種功能, 都由它的實(shí)現(xiàn)類提供
3.ApplicationContext有哪些擴(kuò)展功能
通過(guò)前面的ApplicationContext 的繼承關(guān)系圖,不難看出,ApplicationContext 比BeanFactory多繼承了MessageSource、ResourcePatternResolver、EnvironmentCapable、ApplicationEventPublisher這幾個(gè)接口
這幾個(gè)接口也就是ApplicationEventPublisher的擴(kuò)展功能
MessageSource接口是用來(lái)提供處理國(guó)際化資源的能力,可以識(shí)別多國(guó)語(yǔ)言,相當(dāng)于翻譯
ResourcePatternResolver接口提供的是通配符匹配資源(磁盤或者類路徑下的文件)的能力
ApplicationEventPublisher接口則是可以用來(lái)發(fā)布事件對(duì)象
EnvironmentCapable接口提供了讀取Spring的一些環(huán)境信息的能力
3.1 MessageSource
MessageSource提供了getMessage方法,可以將語(yǔ)言翻譯成不同國(guó)家的語(yǔ)言

System.out.println(context.getMessage("hi", null, Locale.CHINA));
System.out.println(context.getMessage("hi", null, Locale.ENGLISH));
System.out.println(context.getMessage("hi", null, Locale.JAPANESE));這里就能將hi翻譯成中文、英語(yǔ)、日語(yǔ)
因?yàn)檫@個(gè)項(xiàng)目下提供了三個(gè)不同的文件,就會(huì)根據(jù)里面的鍵值對(duì)轉(zhuǎn)化為對(duì)應(yīng)的語(yǔ)言

3.2 ResourcePatternResolver
ResourcePatternResolver提供了getResources方法,可以根據(jù)路徑或者通配符獲取多個(gè)資源
public interface ResourcePatternResolver extends ResourceLoader {
String CLASSPATH_ALL_URL_PREFIX = "classpath*:";
Resource[] getResources(String locationPattern) throws IOException;
}當(dāng)然根據(jù)ResourcePatternResolver的父接口ResourceLoader,可以發(fā)現(xiàn)也可以獲取單個(gè)資源
public interface ResourceLoader {
String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;
Resource getResource(String location);
e org.springframework.util.ClassUtils#forName(String, ClassLoader)
*/
@Nullable
ClassLoader getClassLoader();
}下面舉個(gè)栗子
Resource[] resources = context.getResources("classpath*:META-INF/spring.factories");
for (Resource resource : resources) {
System.out.println(resource);
}classpath是指當(dāng)前類路徑下(在jar包的話就需要像上面這樣加*),而Resource是Spring中對(duì)資源的抽象
3.3 EnvironmentCapable
EnvironmentCapable提供了getEnvironment方法,獲取當(dāng)前Spring的配置信息(環(huán)境變量、application.properties等)
public interface EnvironmentCapable {
/**
* Return the {@link Environment} associated with this component.
*/
Environment getEnvironment();
}可以借助Environment的父接口PropertyResolver提供的getProperty方法獲取某個(gè)配置信息
public interface Environment extends PropertyResolver {
String[] getActiveProfiles();
String[] getDefaultProfiles();
@Deprecated
boolean acceptsProfiles(String... profiles);
boolean acceptsProfiles(Profiles profiles);
}
舉個(gè)栗子
System.out.println(context.getEnvironment().getProperty("java_home"));
System.out.println(context.getEnvironment().getProperty("server.port"));這樣就能獲取到環(huán)境變量和server.port端口號(hào)了
3.4 ApplicationEventPublisher
ApplicationEventPublisher的作用是用來(lái)發(fā)布事件的
@FunctionalInterface
public interface ApplicationEventPublisher {
default void publishEvent(ApplicationEvent event) {
publishEvent((Object) event);
}
void publishEvent(Object event);
}ApplicationEventPublisher提供了一個(gè)publishEvent方法用來(lái)發(fā)布事件
而事件則需要繼承ApplicationEvent,source代表事件源,也就是誰(shuí)發(fā)的事件
public class UserRegisteredEvent extends ApplicationEvent {
public UserRegisteredEvent(Object source) {
super(source);
}
}然后就可以調(diào)用publishEvent來(lái)發(fā)送事件,參數(shù)為context,因?yàn)閏ontext是事件源,也就是context發(fā)的事件
context.publishEvent(new UserRegisteredEvent(context));
除了發(fā)事件,還應(yīng)該有收事件的東西,也就是監(jiān)聽(tīng)器
Spring中任何一個(gè)類都可以作為監(jiān)聽(tīng)器
需要加上 @EventListener注解
然后參數(shù)為事件,也就是發(fā)的事件是什么類型,接收的事件也應(yīng)該是什么類型
@Component
public class Component2 {
private static final Logger log = LoggerFactory.getLogger(Component2.class);
@EventListener
public void aaa(UserRegisteredEvent event) {
log.debug("{}", event);
log.debug("發(fā)送短信");
}
}這樣就可以了,其實(shí)這種操作很像mq,可以用來(lái)異步處理某些業(yè)務(wù)
比如我這里有一個(gè)注冊(cè)方法,然后異步需要發(fā)送短信,那么發(fā)布事件之后,aaa方法就會(huì)異步執(zhí)行
@Component
public class Component1 {
private static final Logger log = LoggerFactory.getLogger(Component1.class);
@Autowired
private ApplicationEventPublisher context;
public void register() {
log.debug("用戶注冊(cè)");
context.publishEvent(new UserRegisteredEvent(this));
}
}到此這篇關(guān)于Spring深入分析容器接口作用的文章就介紹到這了,更多相關(guān)Spring容器接口內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring中的ImportBeanDefinitionRegistrar接口詳解
這篇文章主要介紹了Spring中的ImportBeanDefinitionRegistrar接口詳解,ImportBeanDefinitionRegistrar接口是也是spring的擴(kuò)展點(diǎn)之一,它可以支持我們自己寫(xiě)的代碼封裝成BeanDefinition對(duì)象,注冊(cè)到Spring容器中,功能類似于注解@Service @Component,需要的朋友可以參考下2023-09-09
Spring Boot 集成 Sharding-JDBC + Mybatis-Plus 實(shí)現(xiàn)分庫(kù)分表功能
這篇文章主要介紹了Spring Boot 集成 Sharding-JDBC + Mybatis-Plus 實(shí)現(xiàn)分庫(kù)分表功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08
關(guān)于Spring配置文件加載方式變化引發(fā)的異常詳解
這篇文章主要給大家介紹了關(guān)于Spring配置文件加載方式變化引發(fā)的異常的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Spring具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-01-01
Java 內(nèi)存模型中的happen-before關(guān)系詳解
這篇文章主要為大家介紹了Java 內(nèi)存模型中的happen-before關(guān)系示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
springMVC不掃描controller中的方法問(wèn)題
這篇文章主要介紹了springMVC不掃描controller中的方法問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02

