Spring深入分析容器接口作用
1.容器接口有哪些
在Spring中,容器接口有BeanFactory 接口和ApplicationContext 接口
其繼承關(guān)系如下(Ctrl + alt + u)
由這個繼承關(guān)系圖可以看出,ApplicationContext 接口是 BeanFactory 的子接口。它擴(kuò)展了 BeanFactory 接口的功能
而BeanFactory 才是 Spring 的核心容器, 主要的 ApplicationContext 實現(xiàn)都【組合】了它的功能
那么在哪里可以看見ApplicationContext 類呢?
就在SpringBoot的啟動類中可以看見
@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模式,可以清晰看見ApplicationContext 里面有BeanFactory ,并且BeanFactory 有很多單例
2.BeanFactory能干嘛
使用快捷鍵Ctrl + n查找BeanFactory,然后使用Ctrl + F12即可查看BeanFactory的方法
可以看到,BeanFactory接口的方法看起來并不多,只有g(shù)etBean
實際上控制反轉(zhuǎn)、基本的依賴注入、直至 Bean 的生命周期的各種功能, 都由它的實現(xiàn)類提供
3.ApplicationContext有哪些擴(kuò)展功能
通過前面的ApplicationContext 的繼承關(guān)系圖,不難看出,ApplicationContext 比BeanFactory多繼承了MessageSource、ResourcePatternResolver、EnvironmentCapable、ApplicationEventPublisher這幾個接口
這幾個接口也就是ApplicationEventPublisher的擴(kuò)展功能
MessageSource接口是用來提供處理國際化資源的能力,可以識別多國語言,相當(dāng)于翻譯
ResourcePatternResolver接口提供的是通配符匹配資源(磁盤或者類路徑下的文件)的能力
ApplicationEventPublisher接口則是可以用來發(fā)布事件對象
EnvironmentCapable接口提供了讀取Spring的一些環(huán)境信息的能力
3.1 MessageSource
MessageSource提供了getMessage方法,可以將語言翻譯成不同國家的語言
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翻譯成中文、英語、日語
因為這個項目下提供了三個不同的文件,就會根據(jù)里面的鍵值對轉(zhuǎn)化為對應(yīng)的語言
3.2 ResourcePatternResolver
ResourcePatternResolver提供了getResources方法,可以根據(jù)路徑或者通配符獲取多個資源
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)也可以獲取單個資源
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(); }
下面舉個栗子
Resource[] resources = context.getResources("classpath*:META-INF/spring.factories"); for (Resource resource : resources) { System.out.println(resource); }
classpath是指當(dāng)前類路徑下(在jar包的話就需要像上面這樣加*),而Resource是Spring中對資源的抽象
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方法獲取某個配置信息
public interface Environment extends PropertyResolver { String[] getActiveProfiles(); String[] getDefaultProfiles(); @Deprecated boolean acceptsProfiles(String... profiles); boolean acceptsProfiles(Profiles profiles); }
舉個栗子
System.out.println(context.getEnvironment().getProperty("java_home")); System.out.println(context.getEnvironment().getProperty("server.port"));
這樣就能獲取到環(huán)境變量和server.port端口號了
3.4 ApplicationEventPublisher
ApplicationEventPublisher的作用是用來發(fā)布事件的
@FunctionalInterface public interface ApplicationEventPublisher { default void publishEvent(ApplicationEvent event) { publishEvent((Object) event); } void publishEvent(Object event); }
ApplicationEventPublisher提供了一個publishEvent方法用來發(fā)布事件
而事件則需要繼承ApplicationEvent,source代表事件源,也就是誰發(fā)的事件
public class UserRegisteredEvent extends ApplicationEvent { public UserRegisteredEvent(Object source) { super(source); } }
然后就可以調(diào)用publishEvent來發(fā)送事件,參數(shù)為context,因為context是事件源,也就是context發(fā)的事件
context.publishEvent(new UserRegisteredEvent(context));
除了發(fā)事件,還應(yīng)該有收事件的東西,也就是監(jiān)聽器
Spring中任何一個類都可以作為監(jiān)聽器
需要加上 @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ā)送短信"); } }
這樣就可以了,其實這種操作很像mq,可以用來異步處理某些業(yè)務(wù)
比如我這里有一個注冊方法,然后異步需要發(fā)送短信,那么發(fā)布事件之后,aaa方法就會異步執(zhí)行
@Component public class Component1 { private static final Logger log = LoggerFactory.getLogger(Component1.class); @Autowired private ApplicationEventPublisher context; public void register() { log.debug("用戶注冊"); context.publishEvent(new UserRegisteredEvent(this)); } }
到此這篇關(guān)于Spring深入分析容器接口作用的文章就介紹到這了,更多相關(guān)Spring容器接口內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring中的ImportBeanDefinitionRegistrar接口詳解
這篇文章主要介紹了Spring中的ImportBeanDefinitionRegistrar接口詳解,ImportBeanDefinitionRegistrar接口是也是spring的擴(kuò)展點之一,它可以支持我們自己寫的代碼封裝成BeanDefinition對象,注冊到Spring容器中,功能類似于注解@Service @Component,需要的朋友可以參考下2023-09-09Spring Boot 集成 Sharding-JDBC + Mybatis-Plus 實現(xiàn)分庫分表功能
這篇文章主要介紹了Spring Boot 集成 Sharding-JDBC + Mybatis-Plus 實現(xiàn)分庫分表功能,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-08-08關(guān)于Spring配置文件加載方式變化引發(fā)的異常詳解
這篇文章主要給大家介紹了關(guān)于Spring配置文件加載方式變化引發(fā)的異常的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Spring具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2022-01-01Java 內(nèi)存模型中的happen-before關(guān)系詳解
這篇文章主要為大家介紹了Java 內(nèi)存模型中的happen-before關(guān)系示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10