Spring源码 05 IOC 注解方式
Spring IOC 主要有两种实现方式:XML 和注解。
Spring 3.0 推出了注解注入,成为了现在的主流,也是官方推荐的。
这里分析注解方式。
AnnotationConfigApplicationContext(AppConfig.class)
AppConfig
package cn.sail.ioc;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan
public class AppConfig {
}
UserService
package cn.sail.ioc.service;
import cn.sail.ioc.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class UserService {
@Autowired
UserDao userDao;
public void test() {
System.out.println(userDao);
}
}
UserDao
package cn.sail.ioc.dao;
import org.springframework.stereotype.Component;
@Component
public class UserDao {
}
使用
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = context.getBean(UserService.class);
userService.test();
执行结果:cn.sail.ioc.dao.UserDao@1bd39d3c
接下来开始分析
AnnotationConfigApplicationContext(AppConfig.class)
由于 Spring 源码层级十分复杂,约定如下规则
- 数字 类名:数字代表该类出现的顺序。
- 类数字-数字 方法注释:数字代表该方法在类中执行的层级。
1 AnnotationConfigApplicationContext
由于其父类 AbstractApplicationContext
存在静态代码块,先进入父类的静态代码块。
2 AbstractApplicationContext
2-1 静态代码块
进入
ClassPathXmlApplicationContext
的构造方法,会先进入AbstractApplicationContext
的静态代码块。
static {
/**
* 优先加载上下文关闭事件来防止奇怪的类加载问题
* WebLogic 8.1 在应用程序关闭的时候出现的 BUG
*/
ContextClosedEvent.class.getName();
}
这里是针对 WebLogic 8.1 的特殊处理,与主体逻辑不关,不用过于关注。
1 AnnotationConfigApplicationContext
由于继承了
GenericApplicationContext
,会先执行父类的构造方法。
3 GenericApplicationContext
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
初始化了内部的beanFactory
为DefaultListableBeanFactory
。
1 AnnotationConfigApplicationContext
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
// 构造
this();
// 注册
register(componentClasses);
// 刷新
refresh();
}
1-1 构造
public AnnotationConfigApplicationContext() {
StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
// 读取被注解了的 Bean
this.reader = new AnnotatedBeanDefinitionReader(this);
createAnnotatedBeanDefReader.end();
/*
定义扫描器
可以用来扫描包或者类,继而转换成 Bean 定义信息
但实际上我们扫描包不是 scanner 这个对象,是 Spring 自己 new 的一个 ClassPathBeanDefinitionScanner
这里的 scanner 仅仅是为了程序员能够在外部调用 AnnotationConfigApplicationContext 对象 scan 方法
*/
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
1-2 读取被注解了的 Bean
AnnotatedBeanDefinitionReader(this)
4 AnnotatedBeanDefinitionReader
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
// 将处理注解的基础设施类放入
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
4-1 将处理注解的基础设施类放入
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)
5 AnnotationConfigUtils
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
// 将处理注解的基础设施类放入
registerAnnotationConfigProcessors(registry, null);
}
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
1 AnnotationConfigApplicationContext
1-2 定义扫描器
ClassPathBeanDefinitionScanner(this)
6 ClassPathBeanDefinitionScanner
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
this(registry, true);
}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
this(registry, useDefaultFilters, getOrCreateEnvironment(registry));
}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment) {
this(registry, useDefaultFilters, environment, (registry instanceof ResourceLoader ? (ResourceLoader) registry : null));
}
1 AnnotationConfigApplicationContext
1-1 注册
register(componentClasses)
public void register(Class<?>... componentClasses) {
Assert.notEmpty(componentClasses, "At least one component class must be specified");
StartupStep registerComponentClass = this.getApplicationStartup().start("spring.context.component-classes.register").tag("classes", () -> Arrays.toString(componentClasses));
// 注册
this.reader.register(componentClasses);
registerComponentClass.end();
}
7 AnnotatedBeanDefinitionReader
public void register(Class<?>... componentClasses) {
for (Class<?> componentClass : componentClasses) {
// 注册 Bean
registerBean(componentClass);
}
}
7-1 注册 Bean
registerBean(componentClass)
public void registerBean(Class<?> beanClass) {
// 进一步注册 Bean
doRegisterBean(beanClass, null, null, null, null);
}
7-2 进一步注册 Bean
doRegisterBean(beanClass, null, null, null, null)
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
/*
得到 bean 的描述信息
比如 bean 的注解,作用范围,是否懒加载,注入方式等
*/
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
// 被条件注解 @Conditional 注释的 bean 跳过注册
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(supplier);
/*
解析 bean 的 Scope
比如是否单例 singleton 还是其他
*/
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
// 生成beanName,默认就是类名小写
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
// 通过判断注解内容,设置一些公共属性,比如是否懒加载,优先级等
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
7-3 解析 bean 的 Scope
private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
this.scopeMetadataResolver.resolveScopeMetadata(abd)
8 AnnotationScopeMetadataResolver
public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
ScopeMetadata metadata = new ScopeMetadata();
if (definition instanceof AnnotatedBeanDefinition) {
AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(
annDef.getMetadata(), this.scopeAnnotationType);
if (attributes != null) {
// 获取 @Scope 注解的值,没有默认为 singleton
metadata.setScopeName(attributes.getString("value"));
ScopedProxyMode proxyMode = attributes.getEnum("proxyMode");
if (proxyMode == ScopedProxyMode.DEFAULT) {
proxyMode = this.defaultProxyMode;
}
metadata.setScopedProxyMode(proxyMode);
}
}
return metadata;
}
8-1 获取 @Scope 注解的值
getString("value")
9 AnnotationAttributes
public String getString(String attributeName) {
// 获取必需属性
return getRequiredAttribute(attributeName, String.class);
}
9-1 获取必需属性
getRequiredAttribute(attributeName, String.class)
private <T> T getRequiredAttribute(String attributeName, Class<T> expectedType) {
Assert.hasText(attributeName, "'attributeName' must not be null or empty");
Object value = get(attributeName);
// 断言属性存在
assertAttributePresence(attributeName, value);
// 断言没有异常
assertNotException(attributeName, value);
if (!expectedType.isInstance(value) && expectedType.isArray() &&
expectedType.getComponentType().isInstance(value)) {
Object array = Array.newInstance(expectedType.getComponentType(), 1);
Array.set(array, 0, value);
value = array;
}
// 断言属性类型
assertAttributeType(attributeName, value, expectedType);
return (T) value;
}
7 AnnotatedBeanDefinitionReader
7-3 设置公共属性
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd)
10 AnnotationConfigUtils
public static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) {
processCommonDefinitionAnnotations(abd, abd.getMetadata());
}
static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
if (lazy != null) {
abd.setLazyInit(lazy.getBoolean("value"));
}
else if (abd.getMetadata() != metadata) {
lazy = attributesFor(abd.getMetadata(), Lazy.class);
if (lazy != null) {
abd.setLazyInit(lazy.getBoolean("value"));
}
}
if (metadata.isAnnotated(Primary.class.getName())) {
abd.setPrimary(true);
}
AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
if (dependsOn != null) {
abd.setDependsOn(dependsOn.getStringArray("value"));
}
AnnotationAttributes role = attributesFor(metadata, Role.class);
if (role != null) {
abd.setRole(role.getNumber("value").intValue());
}
AnnotationAttributes description = attributesFor(metadata, Description.class);
if (description != null) {
abd.setDescription(description.getString("value"));
}
}
7 AnnotatedBeanDefinitionReader
7-3 注册 Bean 定义信息
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry)
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
// 使用 beanName 做唯一标识注册
String beanName = definitionHolder.getBeanName();
// 注册 Bean 定义信息
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// 注册所有的别名
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
11 GenericApplicationContext
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
// 注册 Bean 定义信息
this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
}
12 DefaultListableBeanFactory
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
/*
注册前的最后一次校验
这里的校验不同于之前的 XML 文件校验,主要是对于 AbstractBeanDefinition 属性中的 methodOverrides 校验
校验 methodOverrides 是否与工厂方法并存或者 methodOverrides 对应的方法根本不存在
*/
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
/*
注册BeanDefinition,就是将BeanDefinition放入一个map中,key是beanName
注册之前,先查下是否被注册过
*/
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
// 如果对应的 BeanName 已经注册且在配置中配置了 bean 不允许被覆盖,则抛出异常(默认允许覆盖)
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isInfoEnabled()) {
logger.info("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
existingDefinition + "] with [" + beanDefinition + "]");
}
}
else if (!beanDefinition.equals(existingDefinition)) {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
// 如果允许 BeanDefinition 的覆盖,那就向 beanDefinitionMap 中再次存一次值,覆盖之前的值
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
/*
检查 bean 的创建过程是否已经开始了
通过判断一个 set 集合是否为空,因为创建过的 bean 都会放到那个 set 中保存
*/
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
/*
如果项目已经运行了
由于 beanDefinitionMap 是一个全局变量,可能存在并发问题,所以要加锁处理
*/
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
// 更新 beanDefinitionNames 的 list
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
// 更新人工注册的单例集合
removeManualSingletonName(beanName);
}
}
else {
// Still in startup registration phase
/*
仍然在启动注册阶段
注册 beanDefinition
*/
this.beanDefinitionMap.put(beanName, beanDefinition);
// 记录 beanName
this.beanDefinitionNames.add(beanName);
// 更新人工注册的单例集合
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
// 重置所有 beanName 对应的缓存
resetBeanDefinition(beanName);
}
else if (isConfigurationFrozen()) {
clearByTypeCache();
}
}
12-1 更新人工注册的单例集合
removeManualSingletonName(beanName)
private void removeManualSingletonName(String beanName) {
updateManualSingletonNames(set -> set.remove(beanName), set -> set.contains(beanName));
}
private void updateManualSingletonNames(Consumer<Set<String>> action, Predicate<Set<String>> condition) {
// 判断是否已开始创建 Bean
if (hasBeanCreationStarted()) {
synchronized (this.beanDefinitionMap) {
if (condition.test(this.manualSingletonNames)) {
Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
action.accept(updatedSingletons);
this.manualSingletonNames = updatedSingletons;
}
}
}
else {
if (condition.test(this.manualSingletonNames)) {
action.accept(this.manualSingletonNames);
}
}
}
1 AnnotationConfigApplicationContext
1-1 刷新
refresh()
2 AbstractApplicationContext
public void refresh() throws BeansException, IllegalStateException {
// 同步监视器
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
/*
1 准备刷新的上下文环境。例如对系统属性或者环境变量进行准备及验证
设置容器的启动时间
设置关闭状态为 false
设置活跃状态为 true
获取 Environment 对象,并加载当前系统的属性值到 Environment 对象中并进行验证
准备监听器和事件的集合对象,默认为空的集合
*/
prepareRefresh();
/*
2 初始化 BeanFactory,并进行 XML 文件读取
创建容器对象:DefaultListableBeanFactory
加载 XML 配置文件的属性值到当前工厂中,最重要的就是 BeanDefinition
*/
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
/*
3 对 BeanFactory 进行各种功能填充
比如 @Qualifier 与 @Autowired 就是在这一步骤中增加的支持
*/
prepareBeanFactory(beanFactory);
try {
/*
4 定义 Bean 工厂的增强器,子类覆盖方法做额外的处理(此处我们自己一般不做任何扩展工作,但是可以查看 web 中的代码是有具体实现的)
*/
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
/*
5 执行 Bean 工厂的增强器,激活各种 beanFactory 处理器
*/
invokeBeanFactoryPostProcessors(beanFactory);
/*
6 注册 Bean 增强器。注册拦截 Bean 创建的 Bean 处理器,这里只是注册,真正的调用是在 getBean 时候
*/
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
/*
7 为上下文初始化 message 源,即不同语言的消息体,国际化处理
*/
initMessageSource();
/*
8 初始化应用消息广播器,并放入 "applicationEventMulticaster" bean 中
*/
initApplicationEventMulticaster();
/*
9 特定刷新。初始化其他的 bean,留给子类扩展
*/
onRefresh();
/*
10 注册监听器。在所有注册的 bean 中查找 listen bean,注册到消息广播器中
*/
registerListeners();
/*
11 初始化剩下的单实例(非懒加载的)
*/
finishBeanFactoryInitialization(beanFactory);
/*
12 完成刷新过程,通知生命周期处理器 lifecycleProcessor 刷新过程,同时发出 ContextRefreshEvent 通知别人
*/
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex);
}
// 为防止bean资源占用,在异常处理中,销毁已经在前面过程中生成的单件bean
destroyBeans();
// 重置active标志
cancelRefresh(ex);
throw ex;
} finally {
/*
13 清空缓存
*/
resetCommonCaches();
contextRefresh.end();
}
}
}
AbstractApplicationContext
中的refresh()
是整个 IOC 的核心。
后续会对其中的 13 个主要方法做详细解析。
参考
https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click
https://www.bilibili.com/video/BV12Z4y197MU?spm_id_from=333.999.0.0
《Spring源码深度解析(第2版)》
版本
Spring 5.3.15
天河有尽身作涯,星海无边前是岸。