spring-reading./spring-factory/spring-factory-autowireCapa...
xuchengsheng 1cd1b55b9f AutowireCapableBeanFactory接口源码分析 2023-11-27 17:06:52 +08:00
..
src/main/java/com/xcs/spring AutowireCapableBeanFactory/README.md接口源码分析 2023-11-27 17:03:49 +08:00
README.md AutowireCapableBeanFactory接口源码分析 2023-11-27 17:06:52 +08:00
pom.xml spring-factory系列 2023-11-24 17:50:12 +08:00

README.md

AutowireCapableBeanFactory

一、基本信息

✒️ 作者 - Lex 📝 博客 - 掘金 📚 源码地址 - github

二、基本描述

AutowireCapableBeanFactory接口是Spring框架中位于org.springframework.beans.factory.config包下的关键接口,扩展自BeanFactory主要提供了在运行时进行Bean自动装配和创建的高级功能。其核心方法createBean允许动态创建Bean实例并进行自动装配解决了Bean之间的依赖关系而其他方法如autowireBeanapplyBeanPostProcessorsBeforeInitialization则提供了更细粒度的控制和定制点使我们能够在Bean生命周期的不同阶段进行干预实现更灵活的Bean管理和配置。这一接口的存在增强了Spring IoC容器的功能使其能够更好地适应复杂系统的需求。

三、主要功能

  1. Bean的创建和初始化

    • 通过createBean方法可以创建一个新的Bean实例并在创建过程中执行完整的初始化包括所有适用的BeanPostProcessor的回调。
  2. 自动装配

    • 提供了不同的自动装配模式,包括按名称、按类型、按构造函数等,通过autowireautowireBeanProperties方法实现对Bean属性的自动注入。
  3. Bean配置和后处理器应用

    • 通过configureBean方法可以配置已存在的Bean实例应用属性值、工厂回调等同时执行所有BeanPostProcessor的回调。
  4. 定制化初始化和销毁过程

    • 通过initializeBean方法可以在Bean初始化过程中应用定制化的操作例如执行初始化回调、应用后处理器等。还提供了destroyBean方法用于销毁Bean实例。
  5. 解析依赖

    • 通过resolveDependency方法,可以解析指定的依赖关系,支持字段、方法、构造函数等各种依赖注入方式。

四、接口源码

AutowireCapableBeanFactory接口源码中看出它承担了创建、配置和生命周期管理Bean实例的任务。通过定义常量和方法它提供了细粒度的控制包括特定的自动装配策略、初始化过程、属性注入、后处理器应用以及销毁阶段。

/**
 * org.springframework.beans.factory.BeanFactory的扩展接口由能够进行自动装配的Bean工厂实现
 * 前提是它们希望为现有的Bean实例暴露此功能。
 *
 * 此子接口不应在正常应用代码中使用请使用org.springframework.beans.factory.BeanFactory
 * 或org.springframework.beans.factory.ListableBeanFactory以供典型用例使用。
 *
 * 其他框架的集成代码可以利用此接口来连接和填充Spring不控制生命周期的现有Bean实例。
 * 这对于WebWork Actions和Tapestry Page对象等情况特别有用。
 *
 * 请注意此接口不由org.springframework.context.ApplicationContext门面实现
 * 因为它在应用代码中几乎不被使用。尽管如此它仍可从应用程序上下文中访问通过ApplicationContext的
 * org.springframework.context.ApplicationContext#getAutowireCapableBeanFactory()方法获得。
 *
 * 您还可以实现org.springframework.beans.factory.BeanFactoryAware接口
 * 它在ApplicationContext中运行时公开内部BeanFactory以便访问AutowireCapableBeanFactory
 * 只需将传入的BeanFactory强制转换为AutowireCapableBeanFactory。
 *
 * @author Juergen Hoeller
 * @since 04.12.2003
 * @see org.springframework.beans.factory.BeanFactoryAware
 * @see org.springframework.beans.factory.config.ConfigurableListableBeanFactory
 * @see org.springframework.context.ApplicationContext#getAutowireCapableBeanFactory()
 */
public interface AutowireCapableBeanFactory extends BeanFactory {

    /**
     * 常量表示没有外部定义的自动装配。请注意仍将应用BeanFactoryAware等并且将应用基于注释的注入。
     * @see #createBean
     * @see #autowire
     * @see #autowireBeanProperties
     */
    int AUTOWIRE_NO = 0;

    /**
     * 常量表示按名称自动装配Bean属性适用于所有Bean属性设置器     * @see #createBean
     * @see #autowire
     * @see #autowireBeanProperties
     */
    int AUTOWIRE_BY_NAME = 1;

    /**
     * 常量表示按类型自动装配Bean属性适用于所有Bean属性设置器     * @see #createBean
     * @see #autowire
     * @see #autowireBeanProperties
     */
    int AUTOWIRE_BY_TYPE = 2;

    /**
     * 常量,表示自动装配可以满足的最贪婪的构造函数(涉及解析适当的构造函数)。
     * @see #createBean
     * @see #autowire
     */
    int AUTOWIRE_CONSTRUCTOR = 3;

    /**
     * 常量表示通过对Bean类进行内省来确定适当的自动装配策略。
     * @see #createBean
     * @see #autowire
     * @deprecated 自Spring 3.0起:如果使用了混合自动装配策略,请优先使用基于注释的自动装配,以清晰标记自动装配需求。
     */
    @Deprecated
    int AUTOWIRE_AUTODETECT = 4;

    /**
     * 初始化现有Bean实例时使用的后缀以实现“原始实例”约定附加到完全限定的Bean类名称
     * 例如“com.mypackage.MyClass.ORIGINAL”以强制返回给定实例即没有代理等。
     * @since 5.1
     * @see #initializeBean(Object, String)
     * @see #applyBeanPostProcessorsBeforeInitialization(Object, String)
     * @see #applyBeanPostProcessorsAfterInitialization(Object, String)
     */
    String ORIGINAL_INSTANCE_SUFFIX = ".ORIGINAL";

    /**
     * 完全创建给定类的新Bean实例。
     * 执行Bean的完全初始化包括所有适用的BeanPostProcessor BeanPostProcessors。
     * 注意这用于创建一个新实例填充带注释的字段和方法以及应用所有标准的Bean初始化回调。
     * 它不意味着传统的按名称或按类型自动装配属性;对于这些目的,请使用#createBean(Class, int, boolean)。
     * @param beanClass 要创建的Bean的类
     * @return 新的Bean实例
     * @throws BeansException 如果实例化或装配失败
     */
    <T> T createBean(Class<T> beanClass) throws BeansException;

    /**
     * 通过应用实例化后回调和Bean属性后处理例如用于注释驱动的注入来填充给定的Bean实例。
     * 注意:这主要用于(重新)填充带注释的字段和方法,无论是对于新实例还是对于反序列化的实例。
     * 它不意味着传统的按名称或按类型自动装配属性;对于这些目的,请使用#autowireBeanProperties。
     * @param existingBean 现有的Bean实例
     * @throws BeansException 如果装配失败
     */
    void autowireBean(Object existingBean) throws BeansException;

    /**
     * 配置给定的原始Bean自动装配Bean属性应用Bean属性值
     * 应用工厂回调,如{@code setBeanName和{@code setBeanFactory
     * 以及应用所有Bean后处理器包括可能包装给定原始Bean的后处理器     * 这实际上是#initializeBean提供的超集完全应用相应Bean定义指定的配置。
     * 注意此方法需要给定名称的Bean定义
     * @param existingBean 现有的Bean实例
     * @param beanName Bean的名称如果需要将传递给它
     *                 必须存在该名称的Bean定义
     * @return 用于使用的Bean实例原始或包装的其中之一
     * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
     * 如果没有给定名称的Bean定义
     * @throws BeansException 如果初始化失败
     * @see #initializeBean
     */
    Object configureBean(Object existingBean, String beanName) throws BeansException;

    /**
     * 以指定的自动装配策略完全创建给定类的新Bean实例。
     * 此接口支持此处定义的所有常量。
     * 执行Bean的完全初始化包括所有适用的BeanPostProcessor BeanPostProcessors。
     * 这实际上是#autowire提供的超集添加了#initializeBean的行为。
     * @param beanClass 要创建的Bean的类
     * @param autowireMode 按名称或类型,使用此接口中的常量
     * @param dependencyCheck 是否对对象执行依赖关系检查
     *                        (不适用于构造函数的自动装配,因此在这里被忽略)
     * @return 新的Bean实例
     * @throws BeansException 如果实例化或装配失败
     * @see #AUTOWIRE_NO
     * @see #AUTOWIRE_BY_NAME
     * @see #AUTOWIRE_BY_TYPE
     * @see #AUTOWIRE_CONSTRUCTOR
     */
    Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;

    /**
     * 使用指定的自动装配策略实例化给定类的新Bean实例。
     * 此处支持此接口中定义的所有常量。
     * 也可以使用{@code AUTOWIRE_NO调用以便仅应用实例化前回调例如用于注释驱动的注入     * 不会应用标准的BeanPostProcessor BeanPostProcessors回调或对Bean的进一步初始化。
     * 此接口为这些目的提供了不同的、细粒度的操作,例如#initializeBean。
     * 然而如果适用于实例的构建将应用InstantiationAwareBeanPostProcessor回调。
     * @param beanClass 要实例化的Bean的类
     * @param autowireMode 按名称或类型,使用此接口中的常量
     * @param dependencyCheck 是否对Bean实例中的对象引用执行依赖关系检查
     *                        (不适用于构造函数的自动装配,因此在这里被忽略)
     * @return 新的Bean实例
     * @throws BeansException 如果实例化或装配失败
     * @see #AUTOWIRE_NO
     * @see #AUTOWIRE_BY_NAME
     * @see #AUTOWIRE_BY_TYPE
     * @see #AUTOWIRE_CONSTRUCTOR
     * @see #AUTOWIRE_AUTODETECT
     * @see #initializeBean
     * @see #applyBeanPostProcessorsBeforeInitialization
     * @see #applyBeanPostProcessorsAfterInitialization
     */
    Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;

    /**
     * 按名称或类型自动装配给定Bean实例的Bean属性。
     * 也可以使用{@code AUTOWIRE_NO调用以便仅应用实例化后回调例如用于注释驱动的注入     * 不会应用标准的BeanPostProcessor BeanPostProcessors回调或对Bean的进一步初始化。
     * 此接口为这些目的提供了不同的、细粒度的操作,例如#initializeBean。
     * 然而如果适用于实例的配置将应用InstantiationAwareBeanPostProcessor回调。
     * @param existingBean 现有的Bean实例
     * @param autowireMode 按名称或类型,使用此接口中的常量
     * @param dependencyCheck 是否对Bean实例中的对象引用执行依赖关系检查
     * @throws BeansException 如果装配失败
     * @see #AUTOWIRE_BY_NAME
     * @see #AUTOWIRE_BY_TYPE
     * @see #AUTOWIRE_NO
     */
    void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
            throws BeansException;


    /**
     * 将给定bean定义名称的bean定义的属性值应用于给定的bean实例。
     * bean定义可以定义一个完全独立的bean重用其属性值或仅用于现有bean实例的属性值。
     * 此方法不会自动装配bean属性它只应用显式定义的属性值。
     * 使用#autowireBeanProperties方法来自动装配现有的bean实例。
     * 注意此方法需要给定名称的bean定义
     * 不会应用标准的BeanPostProcessor BeanPostProcessors回调或对bean的进一步初始化。
     * 此接口为这些目的提供了不同的、细粒度的操作,例如#initializeBean。
     * 但是如果适用于实例的配置将应用InstantiationAwareBeanPostProcessor回调。
     * @param existingBean 现有的bean实例
     * @param beanName bean工厂中bean定义的名称
     *                 必须存在该名称的bean定义
     * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
     * 如果没有给定名称的bean定义
     * @throws BeansException 如果应用属性值失败
     * @see #autowireBeanProperties
     */
    void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;

    /**
     * 初始化给定的原始bean应用工厂回调例如{@code setBeanName和{@code setBeanFactory
     * 也应用所有bean后处理器包括可能包装给定原始bean的后处理器     * 请注意给定名称的bean工厂不必存在bean定义。
     * 传入的bean名称将仅用于回调但不会与已注册的bean定义进行检查。
     * @param existingBean 现有的bean实例
     * @param beanName bean的名称如果需要将传递给它
     *                 仅传递给BeanPostProcessor BeanPostProcessors
     *                  可以遵循#ORIGINAL_INSTANCE_SUFFIX约定以强制返回给定的实例
     *                  即没有代理等)
     * @return 要使用的bean实例原始的或包装的其中之一
     * @throws BeansException 如果初始化失败
     * @see #ORIGINAL_INSTANCE_SUFFIX
     */
    Object initializeBean(Object existingBean, String beanName) throws BeansException;

    /**
     * 将BeanPostProcessor BeanPostProcessors应用于给定的现有bean实例
     * 调用其{@code postProcessBeforeInitialization方法。返回的bean实例可能是原始bean的包装。
     * @param existingBean 现有的bean实例
     * @param beanName bean的名称如果需要将传递给它
     *                 仅传递给BeanPostProcessor BeanPostProcessors
     *                  可以遵循#ORIGINAL_INSTANCE_SUFFIX约定以强制返回给定的实例
     *                  即没有代理等)
     * @return 要使用的bean实例原始的或包装的其中之一
     * @throws BeansException 如果任何后处理失败
     * @see BeanPostProcessor#postProcessBeforeInitialization
     * @see #ORIGINAL_INSTANCE_SUFFIX
     */
    Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
            throws BeansException;

    /**
     * 将BeanPostProcessor BeanPostProcessors应用于给定的现有bean实例
     * 调用其{@code postProcessAfterInitialization方法。返回的bean实例可能是原始bean的包装。
     * @param existingBean 现有的bean实例
     * @param beanName bean的名称如果需要将传递给它
     *                 仅传递给BeanPostProcessor BeanPostProcessors
     *                  可以遵循#ORIGINAL_INSTANCE_SUFFIX约定以强制返回给定的实例
     *                  即没有代理等)
     * @return 要使用的bean实例原始的或包装的其中之一
     * @throws BeansException 如果任何后处理失败
     * @see BeanPostProcessor#postProcessAfterInitialization
     * @see #ORIGINAL_INSTANCE_SUFFIX
     */
    Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
            throws BeansException;

    /**
     * 销毁给定的bean实例通常来自#createBean应用
     * org.springframework.beans.factory.DisposableBean合同以及注册的
     * DestructionAwareBeanPostProcessor DestructionAwareBeanPostProcessors。
     * 在销毁过程中出现的任何异常都应该被捕获并记录,而不是传播到此方法的调用方。
     * @param existingBean 要销毁的bean实例
     */
    void destroyBean(Object existingBean);

    /**
     * 解析唯一匹配给定对象类型的bean实例如果有的话包括其bean名称。
     * 这实际上是#getBean(Class)的一个变体它保留匹配实例的bean名称。
     * @param requiredType bean必须匹配的类型可以是接口或超类
     * @return bean名称加上bean实例
     * @throws NoSuchBeanDefinitionException 如果没有找到匹配的bean
     * @throws NoUniqueBeanDefinitionException 如果找到多个匹配的bean
     * @throws BeansException 如果无法创建bean
     * @since 4.3.3
     * @see #getBean(Class)
     */
    <T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException;

    /**
     * 为给定的bean名称解析bean实例提供一个依赖项描述符以供目标工厂方法使用。
     * 这实际上是#getBean(String, Class)的一个变体,支持具有
     * org.springframework.beans.factory.InjectionPoint参数的工厂方法。
     * @param name 要查找的bean的名称
     * @param descriptor 用于请求注入点的依赖项描述符
     * @return 相应的bean实例
     * @throws NoSuchBeanDefinitionException 如果没有指定名称的bean
     * @throws BeansException 如果无法创建bean
     * @since 5.1.5
     * @see #getBean(String, Class)
     */
    Object resolveBeanByName(String name, DependencyDescriptor descriptor) throws BeansException;

    /**
     * 解析针对此工厂中定义的bean的指定依赖项。
     * @param descriptor 依赖项的描述符(字段/方法/构造函数)
     * @param requestingBeanName 声明给定依赖项的bean的名称
     * @return 已解析的对象,如果找不到则返回{@code null
     * @throws NoSuchBeanDefinitionException 如果未找到匹配的bean
     * @throws NoUniqueBeanDefinitionException 如果找到多个匹配的bean
     * @throws BeansException 如果由于其他原因导致依赖项解析失败
     * @since 2.5
     * @see #resolveDependency(DependencyDescriptor, String, Set, TypeConverter)
     */
    @Nullable
    Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException;

    /**
     * 解析针对此工厂中定义的bean的指定依赖项。
     * @param descriptor 依赖项的描述符(字段/方法/构造函数)
     * @param requestingBeanName 声明给定依赖项的bean的名称
     * @param autowiredBeanNames 应将所有自动装配的bean的名称用于解析给定依赖项添加到的Set
     * @param typeConverter 用于填充数组和集合的TypeConverter
     * @return 已解析的对象,如果找不到则返回{@code null
     * @throws NoSuchBeanDefinitionException 如果未找到匹配的bean
     * @throws NoUniqueBeanDefinitionException 如果找到多个匹配的bean
     * @throws BeansException 如果由于其他原因导致依赖项解析失败
     * @since 2.5
     * @see DependencyDescriptor
     */
    @Nullable
    Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
            @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;
			
}

五、主要实现

  • AbstractAutowireCapableBeanFactory
    • AbstractAutowireCapableBeanFactoryAutowireCapableBeanFactory接口的抽象实现为Spring框架提供了核心的Bean创建、初始化和销毁功能。它实现了createBean方法支持对Bean的依赖注入、属性值应用、后置处理器的应用以及初始化和销毁阶段的生命周期管理。
classDiagram
    direction BT
    class ResourceLoader {
    	<<interface>>
    }

    class ResourcePatternResolver {
    	<<interface>>
    }

    class PathMatchingResourcePatternResolver {
    }

    ResourcePatternResolver --|> ResourceLoader
    PathMatchingResourcePatternResolver ..|> ResourcePatternResolver

五、最佳实践

使用AnnotationConfigApplicationContext创建了Spring应用程序上下文手动注册了一个后置处理器MyBeanPostProcessor与一个单例BeanMyRepository),最后获取了AutowireCapableBeanFactory

public static void main(String[] args) {
    // 创建 ApplicationContext
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfiguration.class);

    // 配置一个后置处理器用于验证Bean的初始化前后拦截信息打印
    applicationContext.getBeanFactory().addBeanPostProcessor(new MyBeanPostProcessor());
    // 注册一个MyRepository的Bean对象
    applicationContext.getBeanFactory().registerSingleton("myRepository", new MyRepository());

    // 获取 AutowireCapableBeanFactory
    AutowireCapableBeanFactory beanFactory = applicationContext.getAutowireCapableBeanFactory();
}

MyService是一个经典的Spring Bean类通过@Autowired@Value实现了对其他Bean和配置属性的注入。它实现了BeanNameAwareInitializingBeanDisposableBean接口分别在Bean分配名称、属性设置完成后和Bean销毁时执行相应的生命周期方法最后通过调用toString()方法提供了方便的信息展示。

public class MyService implements BeanNameAware, InitializingBean, DisposableBean {

    @Autowired
    private MyRepository myRepository;

    @Value("${java.home}")
    private String javaHome;

    @Override
    public void setBeanName(String name) {
        System.out.println("MyService.setBeanName方法被调用了");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("MyService.afterPropertiesSet方法被调用了");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("MyService.destroy方法被调用了");
    }

    @Override
    public String toString() {
        return "MyService{" +
                "myRepository=" + myRepository +
                ", javaHome='" + javaHome + '\'' +
                '}';
    }
}

MyBeanPostProcessor是一个自定义的Bean后置处理器实现了Spring的BeanPostProcessor接口。在Bean的初始化前后它分别调用postProcessBeforeInitializationpostProcessAfterInitialization方法在这个具体的实现中我们简单地输出了一条日志显示了被处理的Bean的名称。

public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("MyBeanPostProcessor#postProcessBeforeInitialization方法被调用了,Bean名称 = " + beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("MyBeanPostProcessor#postProcessBeforeInitialization方法被调用了,Bean名称 = " + beanName);
        return bean;
    }
}

createBean

通过AutowireCapableBeanFactorycreateBean方法,手动创建了一个MyService类型的Bean实例。

private static void createBean(AutowireCapableBeanFactory beanFactory) {
    MyService myService = beanFactory.createBean(MyService.class);
    System.out.println("调用createBean方法,创建Bean对象 = " + myService);
}

运行结果发现,在MyService的生命周期中,setBeanNameafterPropertiesSet等回调方法都被成功触发说明Bean的初始化过程正常执行。同时MyBeanPostProcessor的后置处理器也在初始化前后成功拦截并输出了Bean的名称。最重要的是MyService中的myRepository和通过@Value注解注入的javaHome属性都成功被注入,表明依赖注入的过程也正常进行。

MyService.setBeanName方法被调用了
MyBeanPostProcessor#postProcessBeforeInitialization方法被调用了,Bean名称 = com.xcs.spring.service.MyService
MyService.afterPropertiesSet方法被调用了
MyBeanPostProcessor#postProcessBeforeInitialization方法被调用了,Bean名称 = com.xcs.spring.service.MyService
调用createBean方法,创建Bean对象 = MyService{myRepository=com.xcs.spring.repository.MyRepository@5b03b9fe, javaHome='D:\install\jdk-11'}

configureBean

通过AutowireCapableBeanFactoryconfigureBean方法手动配置Bean。首先通过registerBeanDefinition方法注册了一个名为 "myService" 的RootBeanDefinition表示要配置的Bean的定义。接着创建了一个新的MyService实例,并通过configureBean方法对该实例进行配置,指定了使用之前注册的 "myService" Bean 定义。在方法执行前后,分别输出了MyService的实例信息,观察是否成功进行了配置。

private static void configureBean(AutowireCapableBeanFactory beanFactory) {
    // 配置一个RootBeanDefinition
    ((DefaultListableBeanFactory) beanFactory).registerBeanDefinition("myService", new RootBeanDefinition(MyService.class));

    MyService myService = new MyService();
    System.out.println("调用configureBean前,MyService = " + myService);
    beanFactory.configureBean(myService, "myService");
    System.out.println("调用configureBean后,MyService = " + myService);
}

运行结果发现,通过configureBean方法配置MyService实例的过程与使用createBean方法创建实例的结果相似。在调用configureBean之前,MyService的实例信息显示属性都为null。然后setBeanNamepostProcessBeforeInitializationafterPropertiesSet等回调方法依次被触发表明Bean的初始化过程正常执行。最终调用configureBean之后,MyService的实例信息显示成功注入了myRepository和通过@Value注解注入的javaHome属性。

调用configureBean,MyService = MyService{myRepository=null, javaHome='null'}
MyService.setBeanName方法被调用了
MyBeanPostProcessor#postProcessBeforeInitialization方法被调用了,Bean名称 = myService
MyService.afterPropertiesSet方法被调用了
MyBeanPostProcessor#postProcessBeforeInitialization方法被调用了,Bean名称 = myService
调用configureBean,MyService = MyService{myRepository=com.xcs.spring.repository.MyRepository@5b03b9fe, javaHome='D:\install\jdk-11'}

autowireBean

通过AutowireCapableBeanFactoryautowireBean方法手动进行Bean的自动装配。首先创建了一个MyService实例,然后通过autowireBean方法对该实例进行自动装配。在方法执行前后,分别输出了MyService的实例信息,观察是否成功进行了自动装配。

private static void autowireBean(AutowireCapableBeanFactory beanFactory) {
    MyService myService = new MyService();
    System.out.println("调用autowireBean前,MyService = " + myService);
    beanFactory.autowireBean(myService);
    System.out.println("调用autowireBean后,MyService = " + myService);
}

运行结果发现,使用AutowireCapableBeanFactoryautowireBean方法对一个新创建的MyService实例进行手动的自动装配。在调用autowireBean之前,MyService的实例信息显示属性都为null。然后调用autowireBean方法后,MyService的实例信息显示成功注入了myRepository属性,该属性引用了com.xcs.spring.repository.MyRepository的实例,以及通过@Value注解注入的javaHome属性,该属性的值为'D:\install\jdk-11'。

然而,需要注意的是,使用autowireBean方法并没有触发BeanNameAware接口中的setBeanName方法、InitializingBean接口中的afterPropertiesSet方法,以及自定义的MyBeanPostProcessor后置处理器的相应回调方法。这是因为autowireBean方法主要关注依赖注入而不涉及到完整的Bean生命周期管理。

调用autowireBean,MyService = MyService{myRepository=null, javaHome='null'}
调用autowireBean,MyService = MyService{myRepository=com.xcs.spring.repository.MyRepository@5b03b9fe, javaHome='D:\install\jdk-11'}

autowire

使用AutowireCapableBeanFactoryautowire方法来创建并自动装配一个MyService类型的Bean。通过指定AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE参数,表示使用类型自动装配。在方法执行后,输出了通过autowire方法创建的MyService实例的信息。

private static void autowire(AutowireCapableBeanFactory beanFactory) {
    Object myService = beanFactory.autowire(MyService.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
    System.out.println("调用autowire方法,创建Bean对象 =" + myService);
}

运行结果发现,通过autowire方法和autowireBean方法获得了相似的结果。

不过,需要注意的是,虽然结果相似,但是这两个方法的使用场景略有不同。autowireBean是直接对一个已有实例进行自动装配,而autowire方法则是根据指定的类型动态创建并自动装配一个Bean。因此具体使用哪一种方法取决于实际的需求和场景。

调用autowire方法,创建Bean对象 =MyService{myRepository=com.xcs.spring.repository.MyRepository@4145bad8, javaHome='D:\install\jdk-11'}

autowireBeanProperties

使用AutowireCapableBeanFactoryautowireBeanProperties方法,对一个新创建的MyService实例进行自动属性装配。首先,创建了一个MyService实例,并输出了其初始状态。然后,通过autowireBeanProperties方法对该实例进行自动属性装配,使用的是AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE规则。最后,输出了autowireBeanProperties后的MyService实例信息,观察是否成功进行了自动属性装配。

private static void autowireBeanProperties(AutowireCapableBeanFactory beanFactory) {
    MyService myService = new MyService();
    System.out.println("调用autowireBeanProperties前,MyService = " + myService);
    beanFactory.autowireBeanProperties(myService, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
    System.out.println("调用autowireBeanProperties后,MyService = " + myService);
}

运行结果发现,通过autowireBeanProperties方法与之前的autowireBeanautowire方法相比,得到了相似的结果。在调用autowireBeanProperties方法之前,MyService的实例信息显示属性都为null。然后调用autowireBeanProperties方法后,MyService的实例信息显示成功注入了myRepository属性,该属性引用了com.xcs.spring.repository.MyRepository的实例,以及通过@Value注解注入的javaHome属性,该属性的值为'D:\install\jdk-11'。

调用autowireBeanProperties前,MyService = MyService{myRepository=null, javaHome='null'}
调用autowireBeanProperties后,MyService = MyService{myRepository=com.xcs.spring.repository.MyRepository@4145bad8, javaHome='D:\install\jdk-11'}

applyBeanPropertyValues

使用AutowireCapableBeanFactoryapplyBeanPropertyValues方法,手动为MyService类型的Bean配置自定义属性值。首先创建了一个PropertyValue实例,表示要设置的属性名为"javaHome",属性值为"这里是我自定义的javaHome路径配置"。接着,通过MutablePropertyValues构建了属性值的集合,并将之前创建的PropertyValue添加到集合中。然后,创建了一个RootBeanDefinition并将属性值集合设置到该Bean定义中。最后通过registerBeanDefinition方法注册了一个名为 "myService" 的Bean定义。在调用applyBeanPropertyValues方法之前,创建了一个新的MyService实例,并输出了其初始状态。然后,调用applyBeanPropertyValues方法后,输出了applyBeanPropertyValues后的MyService实例信息,观察是否成功应用了自定义的属性值。

private static void applyBeanPropertyValues(AutowireCapableBeanFactory beanFactory) {
    PropertyValue propertyValue = new PropertyValue("javaHome", "这里是我自定义的javaHome路径配置");
    MutablePropertyValues propertyValues = new MutablePropertyValues();
    propertyValues.addPropertyValue(propertyValue);

    RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(MyService.class);
    rootBeanDefinition.setPropertyValues(propertyValues);
    // 配置一个RootBeanDefinition
    ((DefaultListableBeanFactory) beanFactory).registerBeanDefinition("myService", rootBeanDefinition);

    MyService myService = new MyService();
    System.out.println("调用applyBeanPropertyValues前,MyService = " + myService);
    beanFactory.applyBeanPropertyValues(myService, "myService");
    System.out.println("调用applyBeanPropertyValues后,MyService = " + myService);
}

运行结果发现,调用applyBeanPropertyValues方法后,并没有触发BeanNameAware接口中的setBeanName方法、InitializingBean接口中的afterPropertiesSet方法,以及自定义的MyBeanPostProcessor后置处理器的相应回调方法。这是因为applyBeanPropertyValues方法主要专注于属性值的应用而不涉及完整的Bean初始化和生命周期管理。最终的运行结果显示myRepository属性为null表明applyBeanPropertyValues方法并没有进行依赖注入。

调用applyBeanPropertyValues,MyService = MyService{myRepository=null, javaHome='null'}
调用applyBeanPropertyValues,MyService = MyService{myRepository=null, javaHome='这里是我自定义的javaHome路径配置'}

initializeBean

使用AutowireCapableBeanFactoryinitializeBean方法,手动初始化MyService类型的Bean。首先创建了一个新的MyService实例,并输出了其初始状态。然后,通过initializeBean方法对该实例进行初始化指定了Bean的名称为 "myService"。在调用方法之后,输出了initializeBean后的MyService实例信息,观察是否成功进行了初始化。

private static void initializeBean(AutowireCapableBeanFactory beanFactory) {
    MyService myService = new MyService();
    System.out.println("调用initializeBean前,MyService = " + myService);
    beanFactory.initializeBean(myService, "myService");
    System.out.println("调用initializeBean前,MyService = " + myService);
}

运行结果发现,myRepositoryjavaHome的值都显示为null,这是因为在调用initializeBean方法时,并没有提供属性值的注入。initializeBean方法主要用于手动触发Bean的初始化阶段包括调用afterPropertiesSet方法和应用Bean后置处理器但它并不负责属性的注入。

调用initializeBean,MyService = MyService{myRepository=null, javaHome='null'}
MyService.setBeanName方法被调用了
MyBeanPostProcessor#postProcessBeforeInitialization方法被调用了,Bean名称 = myService
MyService.afterPropertiesSet方法被调用了
MyBeanPostProcessor#postProcessBeforeInitialization方法被调用了,Bean名称 = myService
调用initializeBean,MyService = MyService{myRepository=null, javaHome='null'}

destroyBean

使用AutowireCapableBeanFactorydestroyBean方法手动销毁destroy一个MyService类型的Bean实例。通过传递新创建的MyService实例作为参数,调用了destroyBean方法。

private static void destroyBean(AutowireCapableBeanFactory beanFactory) {
    beanFactory.destroyBean(new MyService());
}

运行结果发现,在调用destroyBean方法后,MyService实例的销毁方法 destroy 被成功调用。这表明destroyBean方法有效地触发了Bean的销毁阶段执行了实现了DisposableBean接口的destroy方法。

MyService.destroy方法被调用了

resolveDependency

使用AutowireCapableBeanFactoryresolveDependency方法,手动解析一个依赖关系。通过创建一个DependencyDescriptor对象,表示MyService类中的myRepository属性,然后调用resolveDependency方法,尝试解析这个依赖关系。最后,输出解析得到的依赖对象。

private static void resolveDependency(AutowireCapableBeanFactory beanFactory) {
    try {
        DependencyDescriptor dependencyDescriptor = new DependencyDescriptor(MyService.class.getDeclaredField("myRepository"), false);
        Object resolveDependency = beanFactory.resolveDependency(dependencyDescriptor, "myRepository");
        System.out.println("resolveDependency = " + resolveDependency);
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    }
}

运行结果发现,通过调用resolveDependency方法成功解析了依赖关系,将myRepository属性的依赖解析为MyRepository的实例。

resolveDependency = com.xcs.spring.repository.MyRepository@37654521

常见问题

  1. createBean() 和 configureBean()

    • createBean() 用于创建Bean的实例即进行Bean的实例化。它是Bean创建过程中的第一步。
    • configureBean() 则是在Bean实例创建之后进行进一步的配置如应用BeanPostProcessors等。这是在Bean实例化后、初始化之前的阶段。
  2. autowireBean() 和 autowire()

    • autowireBean() 用于对现有的Bean实例进行自动装配将依赖注入到Bean中。
    • autowire() 是在创建Bean实例时使用指定的自动装配模式用于生成新的Bean实例。
  3. autowireBeanProperties() 和 applyBeanPropertyValues()

    • autowireBeanProperties() 主要用于对Bean实例的属性进行自动装配。
    • applyBeanPropertyValues() 则是将属性值应用到Bean实例包括在XML或注解中配置的属性值。
  4. initializeBean()、applyBeanPostProcessorsBeforeInitialization() 和 applyBeanPostProcessorsAfterInitialization()

    • initializeBean() 是Bean生命周期中的最后一步包括初始化和应用BeanPostProcessors等。
    • applyBeanPostProcessorsBeforeInitialization() 用于在初始化之前应用BeanPostProcessors。
    • applyBeanPostProcessorsAfterInitialization() 用于在初始化之后应用BeanPostProcessors。
  5. destroyBean()

    • destroyBean() 用于销毁给定的Bean实例释放资源等。通常在容器关闭时调用。
  6. resolveNamedBean() 和 resolveBeanByName()

    • resolveNamedBean() 主要用于解析指定名称的Bean并返回Bean实例。
    • resolveBeanByName() 则是解析指定名称的Bean定义而不是直接返回Bean实例。
  7. resolveDependency()

    • resolveDependency() 主要用于解析Bean之间的依赖关系特别是在自动装配时。在AbstractAutowireCapableBeanFactorydoResolveDependency()方法中调用。