文章目录
- Spring源码分析(BeanFactory)
- 一、BeanFactory
- 二、ApplicationContext 的父系
- 1、HierarchicalBeanFactory
- 2、ListableBeanFactory
- 3、EnvironmentCapable
- 4、ApplicationEventPublisher
- 5、MessageSource
- 6、ResourcePatternResolver
- 三、ApplicationContext 的实现
- 四、BeanFactory的创建
- 1、Spring中的创建
- 2、SpringBoot中的创建
- 五、DefaultListableBeanFactory
- 1、为什么选择 DefaultListableBeanFactory?
- 2、运行时获取 DefaultListableBeanFactory
Spring源码分析(BeanFactory)
一、BeanFactory
BeanFactory
是最顶层的容器接口,只提供了获取Bean相关的一些方法。
public interface BeanFactory {// 对FactoryBean的转义定义,因为如果使用bean的名字检索FactoryBean得到的对象是工厂生成的对象String FACTORY_BEAN_PREFIX = "&";// 根据bean的名字,在IOC容器中得到bean实例,Object getBean(String name) throws BeansException;// 根据bean的名字,在IOC容器中得到bean实例,args:显式参数(必须为非单例模式)Object getBean(String name, Object... args) throws BeansException;// 根据bean的名字获得对象,并转换为Class类型(可以不用进行类型转换)<T> T getBean(String name, Class<T> requiredType);// 根据bean的类型获得对象(必须是拥有唯一实现类)<T> T getBean(Class<T> requiredType) throws BeansException;// 根据bean的类型获得对象,args:显式参数<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;// 判断IOC容器是否有这个名字的beanboolean containsBean(String name);// 判断这个bean是不是单例 boolean isSingleton(String name) throws NoSuchBeanDefinitionException;// 判断这个bean是不是多例 boolean isPrototype(String name) throws NoSuchBeanDefinitionException;// 获取bean实例的Class类型 Class<?> getType(String name) throws NoSuchBeanDefinitionException;// 这里得到bean的别名,如果根据别名检索,那么其原名也会被检索出来 String[] getAliases(String name);
}
二、ApplicationContext 的父系
ApplicationContext
是更高级的容器接口,继承了许多其他接口,提供了更多的功能。
- 获取 Environment(EnvironmentCapable)
- getBean 的扩展(ListableBeanFactory)
- 事件的发布与监听机制(ApplicationEventPublisher)
- 支持父子容器(HierarchicalBeanFactory)
- 国际化(MessageSource)
- 事件的发布与监听机制(ApplicationEventPublisher)
- 资源访问(ResourcePatternResolver)
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {@NullableString getId();String getApplicationName();String getDisplayName();long getStartupDate();@NullableApplicationContext getParent();// 用于进行手动的 Bean 注入和依赖注入AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;}
1、HierarchicalBeanFactory
HierarchicalBeanFactory
用于表示具有层次结构的 BeanFactory 容器。
-
支持父子容器的关系,一个 BeanFactory 可以有一个或多个父容器。
子容器可以访问父容器中定义的 Bean,但父容器不能访问子容器中定义的 Bean。
-
如果子容器中不存在某个 Bean,则会委托父容器进行查找。
public interface HierarchicalBeanFactory extends BeanFactory {@NullableBeanFactory getParentBeanFactory();boolean containsLocalBean(String name);
}
2、ListableBeanFactory
ListableBeanFactory
扩展了 BeanFactory 接口,提供了额外的功能来 获取 Bean 及其相关信息
public interface ListableBeanFactory extends BeanFactory {// 获取 Bean 的定义信息boolean containsBeanDefinition(String beanName);int getBeanDefinitionCount();String[] getBeanDefinitionNames();// 通过 类型 获取 BeanString[] getBeanNamesForType(ResolvableType type);String[] getBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit);String[] getBeanNamesForType(@Nullable Class<?> type);String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);// 通过 注解 获取BeanString[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);// 获取 <beanName, type><T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;<T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit) throws BeansException;// 获取 <beanName, annotation>Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;// 获取bean的注解@Nullable<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)throws NoSuchBeanDefinitionException;
}
3、EnvironmentCapable
EnvironmentCapable
接口用于获取 Environment
实例
public interface EnvironmentCapable {Environment getEnvironment();
}
Environment
用于表示运行时环境(例如配置文件、系统属性、环境变量等)的抽象,提供了访问应用程序配置信息的统一接口。
public interface Environment extends PropertyResolver {// 返回激活profile名称的数组String[] getActiveProfiles();// 返回默认profile名称的数组String[] getDefaultProfiles();// environment是否支持给定profileboolean acceptsProfiles(Profiles profiles);@Deprecated // 弃用boolean acceptsProfiles(String... profiles);
}
public interface PropertyResolver {// 检查某个属性是否存在boolean containsProperty(String key);// 获取指定属性的值(不存在则返回null)String getProperty(String key);// 获取指定属性的值(不存在则返回默认值)String getProperty(String key, String defaultValue);// 获取指定属性的值,可以指定要返回对象的类型(不存在则返回null)<T> T getProperty(String key, Class<T> targetType);// 获取指定属性的值,可以指定要返回对象的类型(不存在则返回默认值)<T> T getProperty(String key, Class<T> targetType, T defaultValue);// 获取指定属性的值(不存在则抛出异常)String getRequiredProperty(String key) throws IllegalStateException;<T> T getRequiredProperty(String key, Class<T> targetType) throws IllegalStateException;String resolvePlaceholders(String text);String resolveRequiredPlaceholders(String text) throws IllegalArgumentException;
}
4、ApplicationEventPublisher
ApplicationEventPublisher
用于发布应用程序事件并通知所有已注册的事件监听器。
@FunctionalInterface
public interface ApplicationEventPublisher {default void publishEvent(ApplicationEvent event) {publishEvent((Object) event);}void publishEvent(Object event);
}
5、MessageSource
MessageSource
是 Spring Framework 中用于国际化支持的接口之一。
- 它提供了一种统一的方式来访问应用程序中的消息资源,支持多语言和多地区的国际化功能。
public interface MessageSource {String getMessage(String code, Object[] args, String defaultMessage, Locale locale);String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException;String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;
}
6、ResourcePatternResolver
ResourcePatternResolver
加载和访问应用程序中的资源,支持通配符和模式匹配,可以方便地加载多个资源。
public interface ResourcePatternResolver extends ResourceLoader {String CLASSPATH_ALL_URL_PREFIX = "classpath*:";Resource[] getResources(String var1) throws IOException;
}
public interface ResourceLoader {String CLASSPATH_URL_PREFIX = "classpath:";Resource getResource(String var1);@NullableClassLoader getClassLoader();
}
三、ApplicationContext 的实现
ApplicationContext
负责创建和管理应用程序中的所有 Bean 对象,其实现类的区别仅仅在于如何加载配置
AnnotationConfigApplicationContext
:使用「注解方式」加载配置ClassPathXmlApplicationContext
:从「资源根目录」下加载配置FileSystemXmlApplicationContext
:从「文件路径下」加载配置
四、BeanFactory的创建
1、Spring中的创建
// org.springframework.context.support.AbstractApplicationContext@Override
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// ...ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// ...}
}
// org.springframework.context.support.AbstractApplicationContextprotected ConfigurableListableBeanFactory obtainFreshBeanFactory() {// 刷新 BeanFactory(关闭旧的,创建新的)refreshBeanFactory();// 返回 BeanFactoryreturn getBeanFactory();
}
// org.springframework.context.support.AbstractRefreshableApplicationContext@Override
protected final void refreshBeanFactory() throws BeansException {// ...try {// 创建 DefaultListableBeanFactoryDefaultListableBeanFactory beanFactory = createBeanFactory();// ...} catch (IOException ex) {throw new ApplicationContextException(...., ex);}
}protected DefaultListableBeanFactory createBeanFactory() {return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}
可以看到,创建的 BeanFactory 是 DefaultListableBeanFactory
2、SpringBoot中的创建
@SpringBootApplication
public class BasicProjectApplication {public static void main(String[] args) {SpringApplication.run(BasicProjectApplication.class, args);}
}
// org.springframework.boot.SpringApplicationpublic static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {return run(new Class[]{primarySource}, args);
}public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {// 构建 SpringApplication实例 并执行run方法return (new SpringApplication(primarySources)).run(args);
}public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {return (new SpringApplication(primarySources)).run(args);
}public ConfigurableApplicationContext run(String... args) {// Spring容器ConfigurableApplicationContext context = null;try {// 构建Spring容器context = this.createApplicationContext();} // ...
}protected ConfigurableApplicationContext createApplicationContext() {Class<?> contextClass = this.applicationContextClass;if (contextClass == null) {try {switch (this.webApplicationType) {case SERVLET:// AnnotationConfigServletWebServerApplicationContextcontextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);break;case REACTIVE:// AnnotationConfigReactiveWebServerApplicationContextcontextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);break;default:// AnnotationConfigApplicationContextcontextClass = Class.forName(DEFAULT_CONTEXT_CLASS);}}catch (ClassNotFoundException ex) {throw new IllegalStateException("Unable create a default ApplicationContext, please specify an ApplicationContextClass", ex);}}// 构建IoC容器return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}
可以看到,三种 contextClass 都是 GenericApplicationContext 的子类
在实例化之前,会先进行父类 GenericApplicationContext 的初始化
// org.springframework.context.support.GenericApplicationContextpublic GenericApplicationContext() {this.beanFactory = new DefaultListableBeanFactory();
}
可以看到,创建的 BeanFactory 是 DefaultListableBeanFactory
五、DefaultListableBeanFactory
1、为什么选择 DefaultListableBeanFactory?
为什么创建的 BeanFactory 要选择 DefaultListableBeanFactory
呢?
分析一下继承图:
可以看到:
ConfigurableListableBeanFactory
只有一个实现类DefaultListableBeanFactory
DefaultListableBeanFactory
还通过实现右边的AbstractAutowireCapableBeanFactory
通吃了右路
因此,DefaultListableBeanFactory
基本上是最牛的 BeanFactory
了,这也是为什么会选择实例化这个类的原因。
2、运行时获取 DefaultListableBeanFactory
如何在运行时获取 DefaultListableBeanFactory
实例呢?
getAutowireCapableBeanFactory
获取AutowireCapableBeanFactory
AutowireCapableBeanFactory
向下转型得到DefaultListableBeanFactory
public class GetDefaultListableBeanFactory {public static void main(String[] args) {ApplicationContext applicationContext = new AnnotationConfigApplicationContext();DefaultListableBeanFactory autowireCapableBeanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();}
}