From 8c4213cd08b54980608811b5f4cab21630362894 Mon Sep 17 00:00:00 2001 From: xuchengsheng Date: Fri, 24 Nov 2023 17:50:12 +0800 Subject: [PATCH] =?UTF-8?q?spring-factory=E7=B3=BB=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 1 + spring-factory/pom.xml | 24 ++ .../README.md | 359 ++++++++++++++++++ .../pom.xml | 14 + .../AutowireCapableBeanFactoryDemo.java | 42 ++ .../xcs/spring/config/MyConfiguration.java | 18 + .../xcs/spring/controller/MyController.java | 27 ++ .../com/xcs/spring/service/MyService.java | 10 + .../spring/service/impl/MyServiceImpl.java | 14 + .../spring-factory-beanFactory/README.md | 21 + .../spring-factory-beanFactory/pom.xml | 14 + .../java/com/xcs/spring/BeanFactoryDemo.java | 67 ++++ .../main/java/com/xcs/spring/bean/MyBean.java | 18 + .../src/main/resources/beans.xml | 9 + .../pom.xml | 14 + .../spring/ConfigurableBeanFactoryDemo.java | 135 +++++++ .../xcs/spring/config/MyConfiguration.java | 18 + .../com/xcs/spring/service/MyService.java | 10 + .../spring/service/impl/MyServiceImpl.java | 14 + .../pom.xml | 14 + .../ConfigurableListableBeanFactoryDemo.java | 66 ++++ .../xcs/spring/config/MyConfiguration.java | 18 + .../xcs/spring/controller/MyController.java | 14 + .../com/xcs/spring/service/MyService.java | 10 + .../spring/service/impl/MyServiceImpl.java | 14 + .../pom.xml | 14 + .../spring/HierarchicalBeanFactoryDemo.java | 42 ++ .../main/java/com/xcs/spring/bean/MyBean.java | 8 + .../pom.xml | 14 + .../xcs/spring/ListableBeanFactoryDemo.java | 55 +++ .../xcs/spring/config/MyConfiguration.java | 10 + .../com/xcs/spring/service/MyService.java | 11 + 32 files changed, 1119 insertions(+) create mode 100644 spring-factory/pom.xml create mode 100644 spring-factory/spring-factory-autowireCapableBeanFactory/README.md create mode 100644 spring-factory/spring-factory-autowireCapableBeanFactory/pom.xml create mode 100644 spring-factory/spring-factory-autowireCapableBeanFactory/src/main/java/com/xcs/spring/AutowireCapableBeanFactoryDemo.java create mode 100644 spring-factory/spring-factory-autowireCapableBeanFactory/src/main/java/com/xcs/spring/config/MyConfiguration.java create mode 100644 spring-factory/spring-factory-autowireCapableBeanFactory/src/main/java/com/xcs/spring/controller/MyController.java create mode 100644 spring-factory/spring-factory-autowireCapableBeanFactory/src/main/java/com/xcs/spring/service/MyService.java create mode 100644 spring-factory/spring-factory-autowireCapableBeanFactory/src/main/java/com/xcs/spring/service/impl/MyServiceImpl.java create mode 100644 spring-factory/spring-factory-beanFactory/README.md create mode 100644 spring-factory/spring-factory-beanFactory/pom.xml create mode 100644 spring-factory/spring-factory-beanFactory/src/main/java/com/xcs/spring/BeanFactoryDemo.java create mode 100644 spring-factory/spring-factory-beanFactory/src/main/java/com/xcs/spring/bean/MyBean.java create mode 100644 spring-factory/spring-factory-beanFactory/src/main/resources/beans.xml create mode 100644 spring-factory/spring-factory-configurableBeanFactory/pom.xml create mode 100644 spring-factory/spring-factory-configurableBeanFactory/src/main/java/com/xcs/spring/ConfigurableBeanFactoryDemo.java create mode 100644 spring-factory/spring-factory-configurableBeanFactory/src/main/java/com/xcs/spring/config/MyConfiguration.java create mode 100644 spring-factory/spring-factory-configurableBeanFactory/src/main/java/com/xcs/spring/service/MyService.java create mode 100644 spring-factory/spring-factory-configurableBeanFactory/src/main/java/com/xcs/spring/service/impl/MyServiceImpl.java create mode 100644 spring-factory/spring-factory-configurableListableBeanFactory/pom.xml create mode 100644 spring-factory/spring-factory-configurableListableBeanFactory/src/main/java/com/xcs/spring/ConfigurableListableBeanFactoryDemo.java create mode 100644 spring-factory/spring-factory-configurableListableBeanFactory/src/main/java/com/xcs/spring/config/MyConfiguration.java create mode 100644 spring-factory/spring-factory-configurableListableBeanFactory/src/main/java/com/xcs/spring/controller/MyController.java create mode 100644 spring-factory/spring-factory-configurableListableBeanFactory/src/main/java/com/xcs/spring/service/MyService.java create mode 100644 spring-factory/spring-factory-configurableListableBeanFactory/src/main/java/com/xcs/spring/service/impl/MyServiceImpl.java create mode 100644 spring-factory/spring-factory-hierarchicalBeanFactory/pom.xml create mode 100644 spring-factory/spring-factory-hierarchicalBeanFactory/src/main/java/com/xcs/spring/HierarchicalBeanFactoryDemo.java create mode 100644 spring-factory/spring-factory-hierarchicalBeanFactory/src/main/java/com/xcs/spring/bean/MyBean.java create mode 100644 spring-factory/spring-factory-listableBeanFactory/pom.xml create mode 100644 spring-factory/spring-factory-listableBeanFactory/src/main/java/com/xcs/spring/ListableBeanFactoryDemo.java create mode 100644 spring-factory/spring-factory-listableBeanFactory/src/main/java/com/xcs/spring/config/MyConfiguration.java create mode 100644 spring-factory/spring-factory-listableBeanFactory/src/main/java/com/xcs/spring/service/MyService.java diff --git a/pom.xml b/pom.xml index 4937af1..e790663 100644 --- a/pom.xml +++ b/pom.xml @@ -29,6 +29,7 @@ spring-metadata spring-beans spring-context + spring-factory diff --git a/spring-factory/pom.xml b/spring-factory/pom.xml new file mode 100644 index 0000000..ec2c4da --- /dev/null +++ b/spring-factory/pom.xml @@ -0,0 +1,24 @@ + + + + spring-reading + com.xcs.spring + 0.0.1-SNAPSHOT + + + 4.0.0 + spring-factory + pom + + + spring-factory-beanFactory + spring-factory-listableBeanFactory + spring-factory-hierarchicalBeanFactory + spring-factory-configurableBeanFactory + spring-factory-configurableListableBeanFactory + spring-factory-autowireCapableBeanFactory + + + \ No newline at end of file diff --git a/spring-factory/spring-factory-autowireCapableBeanFactory/README.md b/spring-factory/spring-factory-autowireCapableBeanFactory/README.md new file mode 100644 index 0000000..0ae76b1 --- /dev/null +++ b/spring-factory/spring-factory-autowireCapableBeanFactory/README.md @@ -0,0 +1,359 @@ +## AutowireCapableBeanFactory + +### 一、基本信息 + +✒️ **作者** - Lex 📝 **博客** - [掘金](https://juejin.cn/user/4251135018533068/posts) 📚 **源码地址** - [github](https://github.com/xuchengsheng/spring-reading) + +### 三、基本描述 + +`AutowireCapableBeanFactory`接口是Spring框架中位于`org.springframework.beans.factory.config`包下的关键接口,扩展自`BeanFactory`,主要提供了在运行时进行Bean自动装配和创建的高级功能。其核心方法`createBean`允许动态创建Bean实例,并进行自动装配,解决了Bean之间的依赖关系,而其他方法如`autowireBean`和`applyBeanPostProcessorsBeforeInitialization`则提供了更细粒度的控制和定制点,使我们能够在Bean生命周期的不同阶段进行干预,实现更灵活的Bean管理和配置。这一接口的存在增强了Spring IoC容器的功能,使其能够更好地适应复杂系统的需求。 + +### 四、主要功能 + +1. **Bean的创建和初始化:** + + 通过`createBean`方法,可以创建一个新的Bean实例,并在创建过程中执行完整的初始化,包括所有适用的`BeanPostProcessor`的回调。 +2. **自动装配:** + + 提供了不同的自动装配模式,包括按名称、按类型、按构造函数等,通过`autowire`和`autowireBeanProperties`方法实现对Bean属性的自动注入。 +3. **Bean配置和后处理器应用:** + + 通过`configureBean`方法,可以配置已存在的Bean实例,应用属性值、工厂回调等,同时执行所有`BeanPostProcessor`的回调。 +4. **定制化初始化和销毁过程:** + + 通过`initializeBean`方法,可以在Bean初始化过程中应用定制化的操作,例如执行初始化回调、应用后处理器等。还提供了`destroyBean`方法用于销毁Bean实例。 +5. **解析依赖:** + + 通过`resolveDependency`方法,可以解析指定的依赖关系,支持字段、方法、构造函数等各种依赖注入方式。 +6. **Bean实例的生命周期管理:** + + 提供了应用`BeanPostProcessor`的回调,允许在Bean的初始化前后应用定制的处理逻辑,以及执行销毁前的操作。 +7. **解析Bean:** + + 提供了解析指定类型和名称的Bean实例的方法,包括通过`resolveNamedBean`解析唯一匹配的Bean实例。 +8. **依赖检查:** + + 提供`dependencyCheck`方法,用于检查Bean的依赖关系是否满足要求。 +9. **Bean的销毁回调:** + + 通过`destroyBean`方法,允许在销毁Bean实例时执行自定义的清理和回收操作。 +10. **提供Bean的属性赋值:** + + 通过`applyPropertyValues`方法,支持对Bean属性进行手动赋值,实现在运行时动态修改Bean的属性。 +11. **提供Bean的类型转换:** + + 通过`getTypeConverter`方法,支持在运行时进行类型转换,确保属性值正确地转换为目标类型。 +12. **Bean实例的后处理:** + + 通过`postProcessBeanInstance`方法,允许在创建Bean实例后进行自定义的处理,如更改Bean的内部状态或执行其他定制逻辑。 + +### 五、接口源码 + +从`AutowireCapableBeanFactory`接口源码中看出,它承担了创建、配置和生命周期管理Bean实例的任务。通过定义常量和方法,它提供了细粒度的控制,包括特定的自动装配策略、初始化过程、属性注入、后处理器应用以及销毁阶段。 + +```java +/** + * 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 createBean(Class 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) + */ + NamedBeanHolder resolveNamedBean(Class 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 autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException; + +} +``` + +### 六、主要实现 + +### 七、最佳实践 + +### 八、与其他组件的关系 + +### 九、常见问题 \ No newline at end of file diff --git a/spring-factory/spring-factory-autowireCapableBeanFactory/pom.xml b/spring-factory/spring-factory-autowireCapableBeanFactory/pom.xml new file mode 100644 index 0000000..ef94853 --- /dev/null +++ b/spring-factory/spring-factory-autowireCapableBeanFactory/pom.xml @@ -0,0 +1,14 @@ + + + + spring-factory + com.xcs.spring + 0.0.1-SNAPSHOT + + + 4.0.0 + spring-factory-autowireCapableBeanFactory + + \ No newline at end of file diff --git a/spring-factory/spring-factory-autowireCapableBeanFactory/src/main/java/com/xcs/spring/AutowireCapableBeanFactoryDemo.java b/spring-factory/spring-factory-autowireCapableBeanFactory/src/main/java/com/xcs/spring/AutowireCapableBeanFactoryDemo.java new file mode 100644 index 0000000..03ae54e --- /dev/null +++ b/spring-factory/spring-factory-autowireCapableBeanFactory/src/main/java/com/xcs/spring/AutowireCapableBeanFactoryDemo.java @@ -0,0 +1,42 @@ +package com.xcs.spring; + +import com.xcs.spring.config.MyConfiguration; +import com.xcs.spring.controller.MyController; +import com.xcs.spring.service.MyService; +import com.xcs.spring.service.impl.MyServiceImpl; +import org.springframework.beans.factory.config.AutowireCapableBeanFactory; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +/** + * @author xcs + * @date 2023年11月24日 15时02分 + **/ +public class AutowireCapableBeanFactoryDemo { + + public static void main(String[] args) { + // 创建 ApplicationContext + AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfiguration.class); + + // 获取 AutowireCapableBeanFactory + AutowireCapableBeanFactory beanFactory = applicationContext.getAutowireCapableBeanFactory(); + + // 示例:全面创建新的 bean 实例 + MyService myService = beanFactory.createBean(MyServiceImpl.class); + System.out.println("全面创建新的 bean 实例 = " + myService); + + System.out.println(); + + MyController autowireBean = new MyController(); + System.out.println("调用autowireBean方法前,MyController: " + autowireBean); + beanFactory.autowireBean(autowireBean); + System.out.println("调用autowireBean方法后,MyController: " + autowireBean); + + System.out.println(); + + MyController configureBean = new MyController(); + System.out.println("调用configureBean方法前,MyController: " + configureBean); + beanFactory.configureBean(configureBean, "myController"); + System.out.println("调用configureBean方法后,MyController: " + configureBean); + + } +} diff --git a/spring-factory/spring-factory-autowireCapableBeanFactory/src/main/java/com/xcs/spring/config/MyConfiguration.java b/spring-factory/spring-factory-autowireCapableBeanFactory/src/main/java/com/xcs/spring/config/MyConfiguration.java new file mode 100644 index 0000000..da2d5d9 --- /dev/null +++ b/spring-factory/spring-factory-autowireCapableBeanFactory/src/main/java/com/xcs/spring/config/MyConfiguration.java @@ -0,0 +1,18 @@ +package com.xcs.spring.config; + +import com.xcs.spring.service.MyService; +import com.xcs.spring.service.impl.MyServiceImpl; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author xcs + * @date 2023年11月24日 14时17分 + **/ +@Configuration +public class MyConfiguration { + @Bean + public MyService myService() { + return new MyServiceImpl(); + } +} diff --git a/spring-factory/spring-factory-autowireCapableBeanFactory/src/main/java/com/xcs/spring/controller/MyController.java b/spring-factory/spring-factory-autowireCapableBeanFactory/src/main/java/com/xcs/spring/controller/MyController.java new file mode 100644 index 0000000..081269e --- /dev/null +++ b/spring-factory/spring-factory-autowireCapableBeanFactory/src/main/java/com/xcs/spring/controller/MyController.java @@ -0,0 +1,27 @@ +package com.xcs.spring.controller; + +import com.xcs.spring.service.MyService; +import org.springframework.beans.factory.BeanNameAware; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * @author xcs + * @date 2023年11月24日 14时50分 + **/ +public class MyController implements BeanNameAware { + + @Autowired + private MyService myService; + + @Override + public String toString() { + return "MyController{" + + "myService=" + myService + + '}'; + } + + @Override + public void setBeanName(String name) { + System.out.println("MyController.setBeanName: " + name); + } +} diff --git a/spring-factory/spring-factory-autowireCapableBeanFactory/src/main/java/com/xcs/spring/service/MyService.java b/spring-factory/spring-factory-autowireCapableBeanFactory/src/main/java/com/xcs/spring/service/MyService.java new file mode 100644 index 0000000..e20b15f --- /dev/null +++ b/spring-factory/spring-factory-autowireCapableBeanFactory/src/main/java/com/xcs/spring/service/MyService.java @@ -0,0 +1,10 @@ +package com.xcs.spring.service; + +/** + * @author xcs + * @date 2023年11月24日 14时17分 + **/ +public interface MyService { + + void greet(); +} diff --git a/spring-factory/spring-factory-autowireCapableBeanFactory/src/main/java/com/xcs/spring/service/impl/MyServiceImpl.java b/spring-factory/spring-factory-autowireCapableBeanFactory/src/main/java/com/xcs/spring/service/impl/MyServiceImpl.java new file mode 100644 index 0000000..c68dadd --- /dev/null +++ b/spring-factory/spring-factory-autowireCapableBeanFactory/src/main/java/com/xcs/spring/service/impl/MyServiceImpl.java @@ -0,0 +1,14 @@ +package com.xcs.spring.service.impl; + +import com.xcs.spring.service.MyService; + +/** + * @author xcs + * @date 2023年11月24日 14时17分 + **/ +public class MyServiceImpl implements MyService { + @Override + public void greet() { + System.out.println("Hello from MyService!"); + } +} diff --git a/spring-factory/spring-factory-beanFactory/README.md b/spring-factory/spring-factory-beanFactory/README.md new file mode 100644 index 0000000..9540f16 --- /dev/null +++ b/spring-factory/spring-factory-beanFactory/README.md @@ -0,0 +1,21 @@ +## BeanFactory + +### 一、基本信息 + +✒️ **作者** - Lex 📝 **博客** - [掘金](https://juejin.cn/user/4251135018533068/posts) 📚 **源码地址** - [github](https://github.com/xuchengsheng/spring-reading) + +### 二、基本描述 + + + +### 四、主要功能 + +### 五、接口源码 + +### 六、主要实现 + +### 七、最佳实践 + +### 八、与其他组件的关系 + +### 九、常见问题 \ No newline at end of file diff --git a/spring-factory/spring-factory-beanFactory/pom.xml b/spring-factory/spring-factory-beanFactory/pom.xml new file mode 100644 index 0000000..fd2cd37 --- /dev/null +++ b/spring-factory/spring-factory-beanFactory/pom.xml @@ -0,0 +1,14 @@ + + + + spring-factory + com.xcs.spring + 0.0.1-SNAPSHOT + + + 4.0.0 + spring-factory-beanFactory + + \ No newline at end of file diff --git a/spring-factory/spring-factory-beanFactory/src/main/java/com/xcs/spring/BeanFactoryDemo.java b/spring-factory/spring-factory-beanFactory/src/main/java/com/xcs/spring/BeanFactoryDemo.java new file mode 100644 index 0000000..62a2751 --- /dev/null +++ b/spring-factory/spring-factory-beanFactory/src/main/java/com/xcs/spring/BeanFactoryDemo.java @@ -0,0 +1,67 @@ +package com.xcs.spring; + +import com.xcs.spring.bean.MyBean; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.core.ResolvableType; + +/** + * @author xcs + * @date 2023年11月23日 19时17分 + **/ +public class BeanFactoryDemo { + + public static void main(String[] args) { + // 创建 BeanFactory + BeanFactory beanFactory = new AnnotationConfigApplicationContext(MyBean.class).getBeanFactory(); + + // 1. 根据名称获取 bean + Object bean1 = beanFactory.getBean("myBean"); + System.out.println("1.通过名称获取Bean: " + bean1); + + // 2. 根据名称和类型获取 bean + MyBean bean2 = beanFactory.getBean("myBean", MyBean.class); + System.out.println("2.通过名称和类型获取Bean: " + bean2); + + // 3. 根据名称和参数获取 bean + Object bean3 = beanFactory.getBean("myBean", "自定义消息"); + System.out.println("3.通过名称和参数获取Bean: " + bean3); + + // 4. 根据类型获取 bean + MyBean bean4 = beanFactory.getBean(MyBean.class); + System.out.println("4.通过类型获取Bean: " + bean4); + + // 5. 根据类型和参数获取 bean + MyBean bean5 = beanFactory.getBean(MyBean.class, "自定义消息"); + System.out.println("5.通过类型和参数获取Bean: " + bean5); + + // 6. 获取 bean 的 ObjectProvider + ObjectProvider objectProvider = beanFactory.getBeanProvider(MyBean.class); + System.out.println("6.Bean的ObjectProvider: " + objectProvider.getObject()); + + // 7. 获取 bean 的类型 + Class beanType = beanFactory.getType("myBean"); + System.out.println("7.Bean的类型: " + beanType); + + // 8. 判断是否包含某个 bean + boolean containsBean = beanFactory.containsBean("myBean"); + System.out.println("8.是否包含Bean: " + containsBean); + + // 9. 判断 bean 是否为单例 + boolean isSingleton = beanFactory.isSingleton("myBean"); + System.out.println("9.是否为单例: " + isSingleton); + + // 10. 判断 bean 是否为原型 + boolean isPrototype = beanFactory.isPrototype("myBean"); + System.out.println("10.是否为原型: " + isPrototype); + + // 11. 判断 bean 是否匹配指定类型 + boolean isTypeMatch = beanFactory.isTypeMatch("myBean", ResolvableType.forClass(MyBean.class)); + System.out.println("11.是否匹配指定类型: " + isTypeMatch); + + // 12. 获取 bean 的所有别名 + String[] aliases = beanFactory.getAliases("myBean"); + System.out.println("12.Bean的所有别名: " + String.join(", ", aliases)); + } +} diff --git a/spring-factory/spring-factory-beanFactory/src/main/java/com/xcs/spring/bean/MyBean.java b/spring-factory/spring-factory-beanFactory/src/main/java/com/xcs/spring/bean/MyBean.java new file mode 100644 index 0000000..2f595d9 --- /dev/null +++ b/spring-factory/spring-factory-beanFactory/src/main/java/com/xcs/spring/bean/MyBean.java @@ -0,0 +1,18 @@ +package com.xcs.spring.bean; + +/** + * @author xcs + * @date 2023年11月23日 19时18分 + **/ +public class MyBean { + + private String message; + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/spring-factory/spring-factory-beanFactory/src/main/resources/beans.xml b/spring-factory/spring-factory-beanFactory/src/main/resources/beans.xml new file mode 100644 index 0000000..18ebcc4 --- /dev/null +++ b/spring-factory/spring-factory-beanFactory/src/main/resources/beans.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/spring-factory/spring-factory-configurableBeanFactory/pom.xml b/spring-factory/spring-factory-configurableBeanFactory/pom.xml new file mode 100644 index 0000000..0441fd5 --- /dev/null +++ b/spring-factory/spring-factory-configurableBeanFactory/pom.xml @@ -0,0 +1,14 @@ + + + + spring-factory + com.xcs.spring + 0.0.1-SNAPSHOT + + + 4.0.0 + spring-factory-configurableBeanFactory + + \ No newline at end of file diff --git a/spring-factory/spring-factory-configurableBeanFactory/src/main/java/com/xcs/spring/ConfigurableBeanFactoryDemo.java b/spring-factory/spring-factory-configurableBeanFactory/src/main/java/com/xcs/spring/ConfigurableBeanFactoryDemo.java new file mode 100644 index 0000000..af85ca1 --- /dev/null +++ b/spring-factory/spring-factory-configurableBeanFactory/src/main/java/com/xcs/spring/ConfigurableBeanFactoryDemo.java @@ -0,0 +1,135 @@ +package com.xcs.spring; + +import com.xcs.spring.config.MyConfiguration; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.beans.factory.config.Scope; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.core.metrics.ApplicationStartup; + +import java.security.AccessControlContext; + +/** + * @author xcs + * @date 2023年11月24日 13时56分 + **/ +public class ConfigurableBeanFactoryDemo { + + public static void main(String[] args) { + // 创建 ApplicationContext + ConfigurableBeanFactory configurableBeanFactory = new AnnotationConfigApplicationContext(MyConfiguration.class).getBeanFactory(); + + // 示例:设置父级 BeanFactory + configurableBeanFactory.setParentBeanFactory(new DefaultListableBeanFactory()); + + // 示例:设置 ClassLoader + configurableBeanFactory.setBeanClassLoader(ConfigurableBeanFactoryDemo.class.getClassLoader()); + + // 示例:设置临时 ClassLoader + configurableBeanFactory.setTempClassLoader(Thread.currentThread().getContextClassLoader()); + + // 示例:设置是否缓存 bean metadata + configurableBeanFactory.setCacheBeanMetadata(true); + + // 示例:获取BeanPostProcessor数量 + int beanPostProcessorCount = configurableBeanFactory.getBeanPostProcessorCount(); + System.out.println("1.BeanPostProcessor 数量: " + beanPostProcessorCount); + + // 示例:获取所有已注册的 Scope 名称 + String[] scopeNames = configurableBeanFactory.getRegisteredScopeNames(); + System.out.println("2.已注册的 Scope 名称: " + String.join(", ", scopeNames)); + + // 示例:获取注册的 Scope + String customScopeName = "customScope"; + Scope customScope = configurableBeanFactory.getRegisteredScope(customScopeName); + System.out.println("3." + customScopeName + " 对应的 Scope: " + customScope); + + // 示例:获取 ApplicationStartup + ApplicationStartup applicationStartup = configurableBeanFactory.getApplicationStartup(); + System.out.println("4.ApplicationStartup: " + applicationStartup); + + // 示例:获取 AccessControlContext + AccessControlContext accessControlContext = configurableBeanFactory.getAccessControlContext(); + System.out.println("5.AccessControlContext: " + accessControlContext); + + // 示例:拷贝配置 + ConfigurableListableBeanFactory otherFactory = new DefaultListableBeanFactory(); + configurableBeanFactory.copyConfigurationFrom(otherFactory); + + // 示例:注册别名 + String beanName = "myService"; + String alias = "helloService"; + configurableBeanFactory.registerAlias(beanName, alias); + + // 示例:解析别名 + configurableBeanFactory.resolveAliases(value -> value + "_resolved"); + + // 示例:获取合并后的 BeanDefinition + String mergedBeanName = "myService"; + BeanDefinition mergedBeanDefinition = configurableBeanFactory.getMergedBeanDefinition(mergedBeanName); + System.out.println("6.合并后的 BeanDefinition: " + mergedBeanDefinition); + + // 示例:判断是否为 FactoryBean + String factoryBeanName = "myService"; + boolean isFactoryBean = configurableBeanFactory.isFactoryBean(factoryBeanName); + System.out.println("7." + factoryBeanName + " 是否为 FactoryBean: " + isFactoryBean); + + // 示例:设置当前 Bean 是否正在创建 + String currentBeanName = "myService"; + boolean inCreation = true; + configurableBeanFactory.setCurrentlyInCreation(currentBeanName, inCreation); + + // 示例:判断指定的 Bean 是否正在创建 + boolean isCurrentlyInCreation = configurableBeanFactory.isCurrentlyInCreation(currentBeanName); + System.out.println("8." + currentBeanName + " 是否正在创建: " + isCurrentlyInCreation); + + // 示例:注册依赖关系 + String dependentBeanName = "dependentBean"; + configurableBeanFactory.registerDependentBean(beanName, dependentBeanName); + + // 示例:获取所有依赖于指定 Bean 的 Bean 名称 + String[] dependentBeans = configurableBeanFactory.getDependentBeans(beanName); + System.out.println("9." + beanName + " 的所有依赖 Bean 名称: " + String.join(", ", dependentBeans)); + + // 示例:获取指定 Bean 依赖的所有 Bean 名称 + String[] dependencies = configurableBeanFactory.getDependenciesForBean(beanName); + System.out.println("10." + beanName + " 依赖的所有 Bean 名称: " + String.join(", ", dependencies)); + + // 销毁指定 Bean 实例 + Object beanInstance = configurableBeanFactory.getBean(beanName); + configurableBeanFactory.destroyBean(beanName, beanInstance); + + // 销毁所有单例 Bean + configurableBeanFactory.destroySingletons(); + + // 示例:添加 PropertyEditorRegistrar + // configurableBeanFactory.addPropertyEditorRegistrar(null); + + // 示例:注册自定义 PropertyEditor + // configurableBeanFactory.registerCustomEditor(String.class, null); + + // 示例:添加 StringValueResolver + // configurableBeanFactory.addEmbeddedValueResolver(null); + + // 示例:添加 BeanPostProcessor + // configurableBeanFactory.addBeanPostProcessor(null); + + // 示例:注册 Scope + // configurableBeanFactory.registerScope("customScope", null); + + // 示例:设置 ApplicationStartup + // configurableBeanFactory.setApplicationStartup(null); + + // 示例:设置 Bean 表达式解析器 + // configurableBeanFactory.setBeanExpressionResolver(null); + + // 示例:设置 ConversionService + // configurableBeanFactory.setConversionService(null); + + // 示例:设置 TypeConverter + // configurableBeanFactory.setTypeConverter(null); + } + +} diff --git a/spring-factory/spring-factory-configurableBeanFactory/src/main/java/com/xcs/spring/config/MyConfiguration.java b/spring-factory/spring-factory-configurableBeanFactory/src/main/java/com/xcs/spring/config/MyConfiguration.java new file mode 100644 index 0000000..da2d5d9 --- /dev/null +++ b/spring-factory/spring-factory-configurableBeanFactory/src/main/java/com/xcs/spring/config/MyConfiguration.java @@ -0,0 +1,18 @@ +package com.xcs.spring.config; + +import com.xcs.spring.service.MyService; +import com.xcs.spring.service.impl.MyServiceImpl; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author xcs + * @date 2023年11月24日 14时17分 + **/ +@Configuration +public class MyConfiguration { + @Bean + public MyService myService() { + return new MyServiceImpl(); + } +} diff --git a/spring-factory/spring-factory-configurableBeanFactory/src/main/java/com/xcs/spring/service/MyService.java b/spring-factory/spring-factory-configurableBeanFactory/src/main/java/com/xcs/spring/service/MyService.java new file mode 100644 index 0000000..e20b15f --- /dev/null +++ b/spring-factory/spring-factory-configurableBeanFactory/src/main/java/com/xcs/spring/service/MyService.java @@ -0,0 +1,10 @@ +package com.xcs.spring.service; + +/** + * @author xcs + * @date 2023年11月24日 14时17分 + **/ +public interface MyService { + + void greet(); +} diff --git a/spring-factory/spring-factory-configurableBeanFactory/src/main/java/com/xcs/spring/service/impl/MyServiceImpl.java b/spring-factory/spring-factory-configurableBeanFactory/src/main/java/com/xcs/spring/service/impl/MyServiceImpl.java new file mode 100644 index 0000000..c68dadd --- /dev/null +++ b/spring-factory/spring-factory-configurableBeanFactory/src/main/java/com/xcs/spring/service/impl/MyServiceImpl.java @@ -0,0 +1,14 @@ +package com.xcs.spring.service.impl; + +import com.xcs.spring.service.MyService; + +/** + * @author xcs + * @date 2023年11月24日 14时17分 + **/ +public class MyServiceImpl implements MyService { + @Override + public void greet() { + System.out.println("Hello from MyService!"); + } +} diff --git a/spring-factory/spring-factory-configurableListableBeanFactory/pom.xml b/spring-factory/spring-factory-configurableListableBeanFactory/pom.xml new file mode 100644 index 0000000..9bb1cb1 --- /dev/null +++ b/spring-factory/spring-factory-configurableListableBeanFactory/pom.xml @@ -0,0 +1,14 @@ + + + + spring-factory + com.xcs.spring + 0.0.1-SNAPSHOT + + + 4.0.0 + spring-factory-configurableListableBeanFactory + + \ No newline at end of file diff --git a/spring-factory/spring-factory-configurableListableBeanFactory/src/main/java/com/xcs/spring/ConfigurableListableBeanFactoryDemo.java b/spring-factory/spring-factory-configurableListableBeanFactory/src/main/java/com/xcs/spring/ConfigurableListableBeanFactoryDemo.java new file mode 100644 index 0000000..19a21cc --- /dev/null +++ b/spring-factory/spring-factory-configurableListableBeanFactory/src/main/java/com/xcs/spring/ConfigurableListableBeanFactoryDemo.java @@ -0,0 +1,66 @@ +package com.xcs.spring; + +import com.xcs.spring.config.MyConfiguration; +import com.xcs.spring.controller.MyController; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.beans.factory.config.DependencyDescriptor; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +import java.util.Iterator; + +/** + * @author xcs + * @date 2023年11月24日 14时44分 + **/ +public class ConfigurableListableBeanFactoryDemo { + + public static void main(String[] args) throws NoSuchFieldException { + // 创建 ApplicationContext + AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfiguration.class); + + // 获取 ConfigurableListableBeanFactory + ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory(); + + // 忽略指定类型的依赖 + beanFactory.ignoreDependencyType(String.class); + + // 忽略指定接口的依赖 + beanFactory.ignoreDependencyInterface(BeanFactory.class); + + // 注册可解析的依赖 + beanFactory.registerResolvableDependency(ApplicationContext.class, applicationContext); + + // 判断指定的 Bean 是否可以作为自动注入的候选者 + String beanName = "myService"; + + DependencyDescriptor dependencyDescriptor = new DependencyDescriptor(MyController.class.getDeclaredField("myService"), false); + boolean isAutowireCandidate = beanFactory.isAutowireCandidate(beanName, dependencyDescriptor); + System.out.println(beanName + " 是否为自动注入的候选者: " + isAutowireCandidate); + + // 获取指定 Bean 的 BeanDefinition + BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName); + System.out.println(beanName + " 的 BeanDefinition: " + beanDefinition); + + // 获取所有 Bean 的名称的迭代器 + Iterator beanNamesIterator = beanFactory.getBeanNamesIterator(); + System.out.print("所有 Bean 的名称: "); + beanNamesIterator.forEachRemaining(System.out::print); + + // 清除元数据缓存 + beanFactory.clearMetadataCache(); + + // 冻结配置 + beanFactory.freezeConfiguration(); + + // 判断配置是否已冻结 + boolean isConfigurationFrozen = beanFactory.isConfigurationFrozen(); + System.out.println("配置是否已冻结: " + isConfigurationFrozen); + + // 预实例化所有非懒加载的单例 Bean + beanFactory.preInstantiateSingletons(); + } +} diff --git a/spring-factory/spring-factory-configurableListableBeanFactory/src/main/java/com/xcs/spring/config/MyConfiguration.java b/spring-factory/spring-factory-configurableListableBeanFactory/src/main/java/com/xcs/spring/config/MyConfiguration.java new file mode 100644 index 0000000..da2d5d9 --- /dev/null +++ b/spring-factory/spring-factory-configurableListableBeanFactory/src/main/java/com/xcs/spring/config/MyConfiguration.java @@ -0,0 +1,18 @@ +package com.xcs.spring.config; + +import com.xcs.spring.service.MyService; +import com.xcs.spring.service.impl.MyServiceImpl; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author xcs + * @date 2023年11月24日 14时17分 + **/ +@Configuration +public class MyConfiguration { + @Bean + public MyService myService() { + return new MyServiceImpl(); + } +} diff --git a/spring-factory/spring-factory-configurableListableBeanFactory/src/main/java/com/xcs/spring/controller/MyController.java b/spring-factory/spring-factory-configurableListableBeanFactory/src/main/java/com/xcs/spring/controller/MyController.java new file mode 100644 index 0000000..8bebfa7 --- /dev/null +++ b/spring-factory/spring-factory-configurableListableBeanFactory/src/main/java/com/xcs/spring/controller/MyController.java @@ -0,0 +1,14 @@ +package com.xcs.spring.controller; + +import com.xcs.spring.service.MyService; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * @author xcs + * @date 2023年11月24日 14时50分 + **/ +public class MyController { + + @Autowired + private MyService myService; +} diff --git a/spring-factory/spring-factory-configurableListableBeanFactory/src/main/java/com/xcs/spring/service/MyService.java b/spring-factory/spring-factory-configurableListableBeanFactory/src/main/java/com/xcs/spring/service/MyService.java new file mode 100644 index 0000000..e20b15f --- /dev/null +++ b/spring-factory/spring-factory-configurableListableBeanFactory/src/main/java/com/xcs/spring/service/MyService.java @@ -0,0 +1,10 @@ +package com.xcs.spring.service; + +/** + * @author xcs + * @date 2023年11月24日 14时17分 + **/ +public interface MyService { + + void greet(); +} diff --git a/spring-factory/spring-factory-configurableListableBeanFactory/src/main/java/com/xcs/spring/service/impl/MyServiceImpl.java b/spring-factory/spring-factory-configurableListableBeanFactory/src/main/java/com/xcs/spring/service/impl/MyServiceImpl.java new file mode 100644 index 0000000..c68dadd --- /dev/null +++ b/spring-factory/spring-factory-configurableListableBeanFactory/src/main/java/com/xcs/spring/service/impl/MyServiceImpl.java @@ -0,0 +1,14 @@ +package com.xcs.spring.service.impl; + +import com.xcs.spring.service.MyService; + +/** + * @author xcs + * @date 2023年11月24日 14时17分 + **/ +public class MyServiceImpl implements MyService { + @Override + public void greet() { + System.out.println("Hello from MyService!"); + } +} diff --git a/spring-factory/spring-factory-hierarchicalBeanFactory/pom.xml b/spring-factory/spring-factory-hierarchicalBeanFactory/pom.xml new file mode 100644 index 0000000..c7fd394 --- /dev/null +++ b/spring-factory/spring-factory-hierarchicalBeanFactory/pom.xml @@ -0,0 +1,14 @@ + + + + spring-factory + com.xcs.spring + 0.0.1-SNAPSHOT + + + 4.0.0 + spring-factory-hierarchicalBeanFactory + + \ No newline at end of file diff --git a/spring-factory/spring-factory-hierarchicalBeanFactory/src/main/java/com/xcs/spring/HierarchicalBeanFactoryDemo.java b/spring-factory/spring-factory-hierarchicalBeanFactory/src/main/java/com/xcs/spring/HierarchicalBeanFactoryDemo.java new file mode 100644 index 0000000..8a988bc --- /dev/null +++ b/spring-factory/spring-factory-hierarchicalBeanFactory/src/main/java/com/xcs/spring/HierarchicalBeanFactoryDemo.java @@ -0,0 +1,42 @@ +package com.xcs.spring; + +import com.xcs.spring.bean.MyBean; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.HierarchicalBeanFactory; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +/** + * @author xcs + * @date 2023年11月23日 20时22分 + **/ +public class HierarchicalBeanFactoryDemo { + + public static void main(String[] args) { + // 创建父级容器 + AnnotationConfigApplicationContext parentContext = new AnnotationConfigApplicationContext(MyBean.class); + + // 创建子级容器 + AnnotationConfigApplicationContext childContext = new AnnotationConfigApplicationContext(); + childContext.setParent(parentContext); + + // 在子级 BeanFactory 中获取 bean + HierarchicalBeanFactory childHierarchicalBeanFactory = childContext.getBeanFactory(); + System.out.println("1.在子级BeanFactory中获取Bean: " + childHierarchicalBeanFactory.getBean(MyBean.class)); + + // 在父级 BeanFactory 中获取 bean + HierarchicalBeanFactory parentHierarchicalBeanFactory = parentContext.getBeanFactory(); + System.out.println("2.在父级BeanFactory中获取Bean: " + parentHierarchicalBeanFactory.getBean(MyBean.class)); + + // 示例:获取父级 BeanFactory + BeanFactory parentBeanFactory = childHierarchicalBeanFactory.getParentBeanFactory(); + System.out.println("3.获取父级BeanFactory: " + parentBeanFactory); + + // 示例:判断本地 BeanFactory 是否包含指定名称的 bean + boolean containsLocalBean = childHierarchicalBeanFactory.containsLocalBean("myBean"); + System.out.println("4.判断本地BeanFactory是否包含指定名称的Bean: " + containsLocalBean); + + // 示例:判断整个 BeanFactory 是否包含指定名称的 bean + boolean containsBean = childHierarchicalBeanFactory.containsBean("myBean"); + System.out.println("5.判断整个BeanFactory是否包含指定名称的Bean: " + containsBean); + } +} diff --git a/spring-factory/spring-factory-hierarchicalBeanFactory/src/main/java/com/xcs/spring/bean/MyBean.java b/spring-factory/spring-factory-hierarchicalBeanFactory/src/main/java/com/xcs/spring/bean/MyBean.java new file mode 100644 index 0000000..efbe2bf --- /dev/null +++ b/spring-factory/spring-factory-hierarchicalBeanFactory/src/main/java/com/xcs/spring/bean/MyBean.java @@ -0,0 +1,8 @@ +package com.xcs.spring.bean; + +/** + * @author xcs + * @date 2023年11月23日 20时40分 + **/ +public class MyBean { +} diff --git a/spring-factory/spring-factory-listableBeanFactory/pom.xml b/spring-factory/spring-factory-listableBeanFactory/pom.xml new file mode 100644 index 0000000..5e0e09a --- /dev/null +++ b/spring-factory/spring-factory-listableBeanFactory/pom.xml @@ -0,0 +1,14 @@ + + + + spring-factory + com.xcs.spring + 0.0.1-SNAPSHOT + + + 4.0.0 + spring-factory-listableBeanFactory + + \ No newline at end of file diff --git a/spring-factory/spring-factory-listableBeanFactory/src/main/java/com/xcs/spring/ListableBeanFactoryDemo.java b/spring-factory/spring-factory-listableBeanFactory/src/main/java/com/xcs/spring/ListableBeanFactoryDemo.java new file mode 100644 index 0000000..c74e7fb --- /dev/null +++ b/spring-factory/spring-factory-listableBeanFactory/src/main/java/com/xcs/spring/ListableBeanFactoryDemo.java @@ -0,0 +1,55 @@ +package com.xcs.spring; + +import com.xcs.spring.config.MyConfiguration; +import com.xcs.spring.service.MyService; +import org.springframework.beans.factory.ListableBeanFactory; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.core.ResolvableType; +import org.springframework.stereotype.Service; + +import java.util.Map; + +/** + * @author xcs + * @date 2023年11月23日 20时01分 + **/ +public class ListableBeanFactoryDemo { + + public static void main(String[] args) { + // 创建 ListableBeanFactory + ListableBeanFactory beanFactory = new AnnotationConfigApplicationContext(MyConfiguration.class).getBeanFactory(); + + // 示例:判断是否包含指定名称的 bean 定义 + boolean containsBeanDefinition = beanFactory.containsBeanDefinition("myService"); + System.out.println("1.包含Bean定义: " + containsBeanDefinition); + + // 示例:获取工厂中所有 bean 定义的数量 + int beanDefinitionCount = beanFactory.getBeanDefinitionCount(); + System.out.println("2.Bean定义数量: " + beanDefinitionCount); + + // 示例:获取工厂中所有 bean 定义的名称数组 + String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames(); + System.out.println("3.Bean定义名称: " + String.join(", ", beanDefinitionNames)); + + // 示例:获取 ObjectProvider,并懒加载获取 bean 实例 + ObjectProvider objectProvider = beanFactory.getBeanProvider(MyService.class, true); + System.out.println("4.Bean的ObjectProvider: " + objectProvider.getObject()); + + // 示例:根据类型获取所有 bean 的名称 + String[] beanNamesForType = beanFactory.getBeanNamesForType(ResolvableType.forClass(MyService.class)); + System.out.println("5.根据类型获取Bean名称: " + String.join(", ", beanNamesForType)); + + // 示例:根据注解类型获取所有 bean 的名称 + String[] beanNamesForAnnotation = beanFactory.getBeanNamesForAnnotation(Service.class); + System.out.println("6.根据注解获取Bean名称: " + String.join(", ", beanNamesForAnnotation)); + + // 示例:根据注解类型获取所有 bean 实例 + Map beansWithAnnotation = beanFactory.getBeansWithAnnotation(Service.class); + System.out.println("7.根据注解类型获取所有Bean实例: " + beansWithAnnotation); + + // 示例:在指定 bean 上查找指定类型的注解 + Service annotation = beanFactory.findAnnotationOnBean("myService", Service.class); + System.out.println("8.Bean上的注解: " + annotation); + } +} diff --git a/spring-factory/spring-factory-listableBeanFactory/src/main/java/com/xcs/spring/config/MyConfiguration.java b/spring-factory/spring-factory-listableBeanFactory/src/main/java/com/xcs/spring/config/MyConfiguration.java new file mode 100644 index 0000000..ebccb7d --- /dev/null +++ b/spring-factory/spring-factory-listableBeanFactory/src/main/java/com/xcs/spring/config/MyConfiguration.java @@ -0,0 +1,10 @@ +package com.xcs.spring.config; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan("com.xcs.spring.service") +public class MyConfiguration { + +} diff --git a/spring-factory/spring-factory-listableBeanFactory/src/main/java/com/xcs/spring/service/MyService.java b/spring-factory/spring-factory-listableBeanFactory/src/main/java/com/xcs/spring/service/MyService.java new file mode 100644 index 0000000..056df06 --- /dev/null +++ b/spring-factory/spring-factory-listableBeanFactory/src/main/java/com/xcs/spring/service/MyService.java @@ -0,0 +1,11 @@ +package com.xcs.spring.service; + +import org.springframework.stereotype.Service; + +/** + * @author xcs + * @date 2023年11月23日 20时04分 + **/ +@Service +public class MyService { +}