最简 Spring IOC 容器源码分析
唐某 2020-11-26 09:19:12 2020-11-26 84 0
前言
许多文章都是分析的 xml 配置,但是现在 Spring Boot 开发多基于注解。本文从注解
的角度分析 Spring IOC 容器源码。
版本:
- Spring Boot:2.1.6.RELEASE
- Spring FrameWork:5.1.8.RELEASE
- Java 8
文章部分内容参考自:https://www.javadoop.com/post/spring-ioc
BeanDefinition
BeanDefinition 接口定义了一个包含属性、构造器参数、其他具体信息的 bean 实例。
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement { // ConfigurableBeanFactory 中只有 2 种:singleton 和 prototype。 // request, session 等是基于 Web 的扩展 String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON; String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE; // 不重要 int ROLE_APPLICATION = 0; int ROLE_SUPPORT = 1; int ROLE_INFRASTRUCTURE = 2; // 设置父 Bean 的信息(继承父 Bean 的配置信息) void setParentName(@Nullable String parentName); @Nullable String getParentName(); // 设置 Bean 的类名称,要通过反射来生成实例 void setBeanClassName(@Nullable String beanClassName); // 返回当前 Bean 的 class name String getBeanClassName(); void setScope(@Nullable String scope); @Nullable String getScope(); // 是否延迟初始化 void setLazyInit(boolean lazyInit); boolean isLazyInit(); // 设置该 Bean 依赖的所有的 Bean,并非 @Autowire 标记的 void setDependsOn(@Nullable String... dependsOn); @Nullable String[] getDependsOn(); // 设置该 Bean 是否可以注入到其他 Bean 中,只对根据类型注入有效, // 如果根据名称注入,即使这边设置了 false,也是可以的 void setAutowireCandidate(boolean autowireCandidate); boolean isAutowireCandidate(); // 同一接口的多个实现,如果不指定名字,Spring 会优先选择设置 primary 为 true 的 bean void setPrimary(boolean primary); boolean isPrimary(); // 如果该 Bean 采用工厂方法生成,指定工厂名称;否则用反射生成 void setFactoryBeanName(@Nullable String factoryBeanName); @Nullable String getFactoryBeanName(); // 指定工厂类中的 工厂方法名称 void setFactoryMethodName(@Nullable String factoryMethodName); @Nullable String getFactoryMethodName(); // 返回该 bean 的构造器参数 ConstructorArgumentValues getConstructorArgumentValues(); default boolean hasConstructorArgumentValues() { return !getConstructorArgumentValues().isEmpty(); } // Bean 中的属性值,返回的实例在 bean factory post-processing 期间会被更改 MutablePropertyValues getPropertyValues(); default boolean hasPropertyValues() { return !getPropertyValues().isEmpty(); } void setInitMethodName(@Nullable String initMethodName); @Nullable String getInitMethodName(); void setDestroyMethodName(@Nullable String destroyMethodName); @Nullable String getDestroyMethodName(); void setRole(int role); int getRole(); void setDescription(@Nullable String description); @Nullable String getDescription(); // Read-only attributes boolean isSingleton(); boolean isPrototype(); boolean isAbstract(); @Nullable String getResourceDescription(); @Nullable BeanDefinition getOriginatingBeanDefinition();}
AnnotationConfigUtils#processCommonDefinitionAnnotations(...)
```java
static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) { AnnotationAttributes lazy = attributesFor(metad