spring源码深度分析
1.写在前面
本文是对spring源码的深度分析,阅读起来有一定难度,如果对spring应用不太熟练的话,更是难上加难。分析源码是一件枯燥乏味的事情,需要极大的耐心,在这篇的时候也是经历了很大的痛苦,耗费很大精力,前后花了大致一个月的时间。文章很长,我知道不会有很多人看到最后,但是我相信看到最后的一定能有所收获。阅读本文章要对照源码,最好是版本也一致,文章不会贴出所有的源码细节,并且文章不具备跳转,调试的条件,这在集成开发环境是很方便的。
2.搭建环境
新建maven工程,引入如下依赖即可
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
</dependencies>
新建两个类,启动容器,最基本的spring容器就自动了。
@Configuration
public class AppConfig {
}
public class TestBean {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
}
}
3.源码分析
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
代码逻辑比较清晰,分别为
-
创建并初始化容器
-
将启动类注入到容器
-
刷新容器
2.1 创建并初始化容器
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDjavaefinitionScanner(this);
}
主要是两个步骤:
- 创建注解的BeanDefinition读取器
- 创建Java类路径定义的扫描器
2.1.1 创建注解的BeanDefinition读取器
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;
//处理@Conditional注解类,@Conditional注解是按条件注册bean,是springboot实现自动配置的
//的重要基础之一,这里不详细说明,有机会在springboot原理分析中详细介绍
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
下面主要看registerAnnotationConfigProcessors的逻辑。
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
//提取beanFactory
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
//AnnotationAwareOrderComparator类实现了对bean的@Ordered和@Priority注解处理逻辑,可以比较bean的优先级
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
//ContextAnnotationAutowireCandidateResolver实现通过@Autowired注解,依赖其他bean的逻辑,在bean寻找并注入依赖时调用,后面会有涉及
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
//下面的逻辑就是初始化几个spring注解实现的核心bean,spring容器内置的几个bean,就在这里注入到容器,他们的名字都以internal开头,
//但实现的机制不一样,有的实现BeanDefinitionRegistryPostProcessor接口,有的实现BeanPostProcessor接口,
//就是说调用这些类的方法的时机不一样,这点很重要
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
//ConfigurationClassPostProcessor注入到容器中,这里我们要关注类本身实现的功能和spring容器什么时候调用的该类的方法。
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, javaEVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
2.1.1.1 ConfigurationClassPostProcessor类
这个类处理当bean的方法中标记了@Bean注解或者类标记了@Configuration注解。
通过查看源码可以得出,该类实现了BeanDefinitionRegistryPostProcessor接口,我们只需要关注下面的两个方法。这两个方法是在容器将所有bean加载为BeanDeifinition后,bean实例化前执行的,目的就是在bean实例化前给个机会修改BeanDefinition的内容,进而影响bean实例化的,具体的用法参考BeanFactoryPostProcessor与BeanDefinitionRegistryPostProcessor用法与原理,并且postProcessBeanDefinitionRegistry方法会先执行,postProcessBeanFactory后执行,这里的逻辑会在实际调用的时候分析。
2.1.1.2 AutowiredAnnotationBeanPostProcessor类
这个类处理@Autowired,@Value,@Inject注解,实现类依赖自动注入的解析逻辑。这个类间接的实现了BeanPostProcessor接口,基于BeanPostProcessor后置处理原理,实现原理参考BeanPostProcessor后置处理器原理与应用
2.1.1.3 CommonAnnotationBeanPostProcessor类
解析@PreDestroy,@PostConstruct,@Resource等注解,也是个实现BeanPostProcessor的接口。
2.1.1.4 PersistenceAnnotationBeanPostProcessor类
这个类与jpa访问数据库相关,这里不做介绍。
2.1.1.5 EventListenerMethodProcessor和DefaultEventListenerFactory类
这两个之所以在一起介绍,主要是跟spring的事件监听机制有关,请参考spring的ApplicationEvent事件监听机制原理与应用
这几个spring容器启动时就注册类,实现类基于注解的spring容器的基本功能,这几个bean有什么作用,在哪调用的,会在后面的分析中说明,当前只需要知道这几个基础类是在启动时注册的即可。
2.1.2 创建Java类路径定义的扫描器
当实例化AnnotationConfigApplicationContext传入的是包名时,ClassPathBeanDefinitionScanner这个类会识别包中所有标记了@Component,@Repository,@Service,@Controller主机的类,注册到容器中。
2.2 将启动类注入到容器
从register(componentClasses);开始分析。这里的componentClasses参数是一个可变参数列表,可以传入多个启动配置,本例子只传入了一个AppConfig空配置类。跟踪代码进入到下面方法;
public void register(Class<?>... componentClasses) {
//遍历处理每一个配置列
for (Class<?> componentClass : componentClasses) {
registerBean(componentClass);
}
}
省略了几个中间的方法传递调用直接进入处理逻辑
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
//将配置类封装成基于注解的BeanDefinition
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
//这里判断当前bean是否存在@Conditional注解,如果不满足条件得话就直接跳过,不处理。通常主配置类不带条件,就是说这里不会跳过。
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(supplier);
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);//解析scope
abd.setScope(scopeMetadata.getScopeName());//默认scope时singleton
//获取默认beanName,类名首字母小写
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//解析通用得注解属性,包括@Lazy,@Primary,@DependsOn,@Role,@Description
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (qualifiers != null) {
//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) {
//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);
}
2.3 刷新容器
代码入口refresh();这个方法时整个spring的核心,也是最复杂的,涉及的内容很多,这里的每一个方法基本上代表一个spring的功能,逻辑比较清晰,下面逐个分析,整个代码在同步块中。
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since wejava
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
2.3.1准备刷新(prepareRefresh())
做一下初始化准备,没有什么重要的逻辑。
2.3.2 获取BeanFactory(obtainFreshBeanFactory())
获取BeanFactory,本案例通过注解启动,obtainFreshBeanFactory()方法会执行GenericApplicationContext类的refreshBeanFactory() 方法,这个方法除了置了一个标记,没有其他逻辑。
2.3.3 准备BeanFactory(prepareBeanFactory(beanFactory))
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//解析依赖时,忽略这几个接口
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
//与上面的忽略相反,这几个bean是可以被依赖注入的
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
//注册一个事件监听器后置处理器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
总体上,这个方法向spring容器注册了几个基础的bean,这几个bean实现spring的以下功能机制的。
-
注册StandardBeanExpressionResolver,支持表达式解析
-
注册ResourceEditorRegistrar,支持属性编辑
-
注册ApplicationContextAwareProcessor,支持Aware机制,获取spring的常用对象,实现细节参考Spring的Aware机制原理与应用
-
注册ApplicationListenerDetector,实现事件监听机制,实现原理参考spring的ApplicationEvent事件监听机制原理与应用
2.3.4 空方法(postProcessBeanFactory(beanFactory))
空方法,用于子类实现扩展。
2.3.5 调用BeanFactoryPostProcessor的处理逻辑(invokeBeanFactoryPostProcessors(beanFactory))
这个方法执行时,容器中的bean还没有被实例化,容器中存储的都是代表bean的BeanDefinition,这个方法就是针对BeanDefinition集合处理。
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
进入PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors方法。这里的详细逻辑我在BeanFactoryPostProcessor与BeanDefinitionRegistryPostProcessor用法与原理的原理分析部分详细分析过,请移步。
2.3.6 注册BeanProcessor后置处理器(registerBeanPostProcessors(beanFactory))
注册BeanProcessor到容器,并不是调用BeanProcessor中的方法,注册的源码分析在BeanPostProcessor后置处理器原理与应用中的原理实现中有介绍,这里不重复。
2.3.7 初始化消息源(initMessageSource())
这部分与spring的核心关联不大,省略。
2.3.8 初始化事件广播器(initApplicationEventMulticaster())
在spring的ApplicationEvent事件监听机制原理与应用的事件发布原理章节中有介绍
2.3.9 空方法(onRefresh())
2.3.10 注册事件监听器(registerListeners())
protected void registerListeners() {
// Register statically specified listeners first.
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
正常的事件监听器都是在BeanProcessor中注册的,这里注册的事件监听器是特殊的,在容器启动时就注册的,还没到容器初始化bean。还有一个逻辑是
如果是early事件,这里直接就发布事件了。
2.3.11 实例化bean(finishBeanFactoryInitialization(beanFactory))
在这个方法里会实例化,初始化所有的不是懒加载的bean。这个过程相当复杂,耐心看下去。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
我们关注最后一行代码,上面的逻辑暂时忽略。其实我们看spring的源码主要关注重要的逻辑,主要功能的实现思路,没必要过分关注实现的所有细节,因为对于任何框架来说,代码量巨大,没有那么多精力充分阅读所有的实现细节。
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); //合并beanDefinition
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//实例化的前提是:不是抽象类,是单例的,不是懒加载的
if (isFactoryBean(beanName)) {
//判断工厂bean
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean)


2742

被折叠的 条评论
为什么被折叠?



