Spring源码分析(BeanFactory)

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容器是否有这个名字的bean
    boolean 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 {

    @Nullable
    String getId();

    String getApplicationName();

    String getDisplayName();

    long getStartupDate();

    @Nullable
    ApplicationContext getParent();

    // 用于进行手动的 Bean 注入和依赖注入
    AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;

}

1、HierarchicalBeanFactory

HierarchicalBeanFactory 用于表示具有层次结构的 BeanFactory 容器。

  • 支持父子容器的关系,一个 BeanFactory 可以有一个或多个父容器。

    子容器可以访问父容器中定义的 Bean,但父容器不能访问子容器中定义的 Bean。

  • 如果子容器中不存在某个 Bean,则会委托父容器进行查找。

public interface HierarchicalBeanFactory extends BeanFactory {
    @Nullable
    BeanFactory getParentBeanFactory();

    boolean containsLocalBean(String name);
}

2、ListableBeanFactory

ListableBeanFactory 扩展了 BeanFactory 接口,提供了额外的功能来 获取 Bean 及其相关信息

public interface ListableBeanFactory extends BeanFactory {
    // 获取 Bean 的定义信息
    boolean containsBeanDefinition(String beanName);
    int getBeanDefinitionCount();
    String[] getBeanDefinitionNames();
    
    // 通过 类型 获取 Bean
    String[] 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);
    
    // 通过 注解 获取Bean
    String[] 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是否支持给定profile
    boolean 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);

    @Nullable
    ClassLoader 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.AbstractApplicationContext

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    // 刷新 BeanFactory(关闭旧的,创建新的)
    refreshBeanFactory();
    // 返回 BeanFactory
    return getBeanFactory();
}
// org.springframework.context.support.AbstractRefreshableApplicationContext

@Override
protected final void refreshBeanFactory() throws BeansException {
    // ...
    try {
        // 创建 DefaultListableBeanFactory
        DefaultListableBeanFactory 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.SpringApplication

public 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:
                    // AnnotationConfigServletWebServerApplicationContext
                    contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
                    break;
                case REACTIVE:
                    // AnnotationConfigReactiveWebServerApplicationContext
                    contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
                    break;
                default:
                    // AnnotationConfigApplicationContext
                    contextClass = 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.GenericApplicationContext

public GenericApplicationContext() {
    this.beanFactory = new DefaultListableBeanFactory();
}

可以看到,创建的 BeanFactory 是 DefaultListableBeanFactory

五、DefaultListableBeanFactory

1、为什么选择 DefaultListableBeanFactory?

为什么创建的 BeanFactory 要选择 DefaultListableBeanFactory 呢?

分析一下继承图:

在这里插入图片描述

可以看到:

  • ConfigurableListableBeanFactory 只有一个实现类 DefaultListableBeanFactory
  • DefaultListableBeanFactory 还通过实现右边的 AbstractAutowireCapableBeanFactory 通吃了右路

因此,DefaultListableBeanFactory 基本上是最牛的 BeanFactory 了,这也是为什么会选择实例化这个类的原因。

2、运行时获取 DefaultListableBeanFactory

如何在运行时获取 DefaultListableBeanFactory 实例呢?

  1. getAutowireCapableBeanFactory 获取 AutowireCapableBeanFactory
  2. AutowireCapableBeanFactory 向下转型得到 DefaultListableBeanFactory
public class GetDefaultListableBeanFactory {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        DefaultListableBeanFactory autowireCapableBeanFactory = 
            (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

scj1022

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值