最近学习了一段时间spring 源码,写一些学习笔记,大家互相交流一下。
spring 容器的启动过程,主要做了两件事情,beanDefinition的加载 和 bean的创建
首先我们来看下beanFactory 接口的继承图 beanFactory继承图.png在接下来的源码分析中,我们分析两个类 AnnotationConfigApplicationContext, DefaultListableBeanFactory
AnnotationConfigApplicationContext这个类是基于注解的容器类,它实现了BeanFactory和BeanDefinitionRegistry两个接口,拥有bean对象管理和beanDefinition注册的功能,同时在这个类里边还拥有一个DefaultListableBeanFactory 对象。
DefaultListableBeanFactory 这个类也实现了BeanFactory和BeanDefinitionRegistry两个接口,拥有bean对象管理和beanDefinition注册的功能,AnnotationConfigApplicationContext是委托DefaultListableBeanFactory来实现bean对象管理和beanDefinition的注册。
beanDefinition的加载
beanDefition个是一个接口,是用来存储Bean定义的一些信息的,比如ClassName,Scope,init-methon,等等。它的实现有RootBeanDefination,AnnotatedGenericBeanDefinition等。
首先我们通过一个小的demo,来启动一个spring容器。
public static void main(String[] args) {
AnnotationConfigApplicationContext cxt = new AnnotationConfigApplicationContext(MainConfig.class);
Car car = (Car) cxt.getBean("car");
System.out.println(car.getName());
}
@Configuration
@Import(value = {TimeProxy.class,LogProxy.class})
@ComponentScan(value = "com.thread.proyx")
public class MainConfig {
@Bean
public Car car(){
return new Car();
}
@Bean
public Tran tran(){
return new Tran();
}
}
接下来我们对源码进行分析,创建AnnotationConfigApplicationContext对象
public AnnotationConfigApplicationContext(Class... componentClasses) {
//加载spring内部类的beanDefinition到容器中
this();
//加载配置类的beanDefinition
this.register(componentClasses);
//加载其它类beanDefinition,创建bean实例化...
this.refresh();
}
this构造方法,给我们创建了AnnotatedBeanDefinitionReader注解bean定义读取,ClassPathBeanDefinitionScanner 类路径bean定义扫描器,还有它的父类构造方法,创建了 DefaultListableBeanFactory 对象,
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
//父类构造器
public GenericApplicationContext() {
this.customClassLoader = false;
this.refreshed = new AtomicBoolean();
//创建beanFactory
this.beanFactory = new DefaultListableBeanFactory();
}
AnnotatedBeanDefinitionReader对象的创建,是用来加载spring内部类的beanDefinition,我们从源码可以看出
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
//省略一些代码...
//注册注解形式的配置处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {
//判断registry是否为空
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
//省略配置beanFactory的一些代码
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet(8);
RootBeanDefinition def;
//ConfigurationClassPostProcessor类型的beanDefinition注册到容器中,这个类型很重要,接下来,我们自己注入的类,通过扫描器扫描的类,解析方法就在这个类里边。
if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalConfigurationAnnotationProcessor")) {
def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"));
}
//解析autowired自动装配的beanDefinition注册到容器中(这是个后置处理器)
if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalAutowiredAnnotationProcessor")) {
def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"));
}
//省略了一些代码(spring内部需要注册到容器中的beanDefinition)
return beanDefs;
}
到这里,我们的AnnotatedBeanDefinitionReader对象就创建完成了,AnnotatedBeanDefinitionReader对象的创建过程,就是将spring内部的一些处理器的beanDefinition加载到容器中。
ClassPathBeanDefinitionScanner(类路径bean定义扫描器)对象的创建,就是创建默认的扫描器,代码比较简单。this方法已经完成,主要就是加载spring内部类的beanDefinition到容器中。
registe方法,传入的参数,就是我们创建的配置类,这个方法是把我们配置类的beanDefinition加载到容器中
public void register(Class... componentClasses) {
Assert.notEmpty(componentClasses, "At least one component class must be specified");
//this方法创建的reader对象,调用register方法,传入配置类
this.reader.register(componentClasses);
}
public void register(Class... componentClasses) {
Class[] var2 = componentClasses;
int var3 = componentClasses.length;
for(int var4 = 0; var4 < var3; ++var4) {
Class<?> componentClass = var2[var4];
//调用注册配置类的beanDefinition
this.registerBean(componentClass);
}
}
public void registerBean(Class<?> beanClass) {
this.doRegisterBean(beanClass, (String)null, (Class[])null, (Supplier)null, (BeanDefinitionCustomizer[])null);
}
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier, @Nullable BeanDefinitionCustomizer[] customizers) {
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
//省略一些代码
//创建beanDefinition的包装类
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
//继续调用注册bean定义方法
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
}
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
String beanName = definitionHolder.getBeanName();
//BeanDefinitionRegistry 是接口,调用方法实现类的方法,前面说到DefaultListableBeanFactory 实现了该接口,直接调用 DefaultListableBeanFactory 的registerBeanDefinition 方法
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
String[] aliases = definitionHolder.getAliases();
//配置别名
if (aliases != null) {
String[] var4 = aliases;
int var5 = aliases.length;
for(int var6 = 0; var6 < var5; ++var6) {
String alias = var4[var6];
registry.registerAlias(beanName, alias);
}
}
}
//在 DefaultListableBeanFactory的 registerBeanDefinition方法中有端代码
this.beanDefinitionMap.put(beanName, beanDefinition);
说明了把beanDefinition保存在 map中,beanName为key,beanDefinition为value;这里是把配置类的bean定义注册到容器中;到这里 registe方法就完成了,当前只是把配置类的bean定义注册完成。我们自己注入的bean,扫描的bean定义还没有加载。
AnnotationConfigApplicationContext的最后一个方法 refresh,这里边是注册@bean,@ComponentScan, @Import 等注入的beanDefinition,创建bean实例等操作。
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
//这个方法很重要,其它beanDefinition注册,都在这里边实现,本篇接下来主要介绍这个方法的实现。
this.invokeBeanFactoryPostProcessors(beanFactory);
//注册bean后置处理器,aop用到
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
//初始化事件多播器,事件监听使用
this.initApplicationEventMulticaster();
this.onRefresh();
//事件监听器
this.registerListeners();
//这个方法很重要,完成bean实例化的创建,包括解决循环依赖,这篇里边不做介绍,
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
接下来看下我们来看invokeBeanFactoryPostProcessors(beanFactory)方法里边的源码
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//传入参数beanFactory和 beanFactory后置处理器
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());
//省略一些代码
}
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
//其它省略的代码,一些看不懂,
//这个方法是最主要的处理方法,继续调用,还没有进去到处理的地方
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
private static void invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
Iterator var2 = postProcessors.iterator();
while(var2.hasNext()) {
BeanDefinitionRegistryPostProcessor postProcessor = (BeanDefinitionRegistryPostProcessor)var2.next();
//这里就是调用ConfigurationClassPostProcessor类里边的方法,ConfigurationClassPostProcessor就是刚开始注册的那个很重要的内部bean定义
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
//这里就是ConfigurationClassPostProcessor的方法
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
//省略一些代码
this.registriesPostProcessed.add(registryId);
//这里才是处理配置bean定义的主要方法,接着往下看
this.processConfigBeanDefinitions(registry);
}
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
//省略一些配置的代码
//创建配置类的解析器
ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet(configCandidates);
HashSet alreadyParsed = new HashSet(configCandidates.size());
do {
//解析配置类里边@ComponentScan 注解扫描的bean,加载beanDefinition到容器中,并找到@bean,@Import 等注解引入的bean
parser.parse(candidates);
//把上面找到但没有加载的bean定义,加载到容器中
this.reader.loadBeanDefinitions(configClasses);
}while(!candidates.isEmpty())
}
接下来我们看下parse方法里边的源码,
public void parse(Set<BeanDefinitionHolder> configCandidates) {
Iterator var2 = configCandidates.iterator();
while(var2.hasNext()) {
BeanDefinitionHolder holder = (BeanDefinitionHolder)var2.next();
BeanDefinition bd = holder.getBeanDefinition();
try {
if (bd instanceof AnnotatedBeanDefinition) {
//注解的bean定义,从这个方法进入
this.parse(((AnnotatedBeanDefinition)bd).getMetadata(), holder.getBeanName());
} else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition)bd).hasBeanClass()) {
this.parse(((AbstractBeanDefinition)bd).getBeanClass(), holder.getBeanName());
} else {
this.parse(bd.getBeanClassName(), holder.getBeanName());
}
} catch (BeanDefinitionStoreException var6) {
throw var6;
} catch (Throwable var7) {
throw new BeanDefinitionStoreException("Failed to parse configuration class [" + bd.getBeanClassName() + "]", var7);
}
}
this.deferredImportSelectorHandler.process();
}
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
this.processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
}
protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
do {
//这里是spring做事的处理方法
sourceClass = this.doProcessConfigurationClass(configClass, sourceClass, filter);
} while(sourceClass != null);
this.configurationClasses.put(configClass, configClass);
}
@Nullable
protected final ConfigurationClassParser.SourceClass doProcessConfigurationClass(ConfigurationClass configClass, ConfigurationClassParser.SourceClass sourceClass, Predicate<String> filter) throws IOException {
// 处理 @ComponentScan 注解类,重点,先获取加了@ComponentScan注解的配置类
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
Iterator var14 = componentScans.iterator();
while(var14.hasNext()) {
AnnotationAttributes componentScan = (AnnotationAttributes)var14.next();
// 开始扫描指定package下的所有Bean,那些加了@Component,@Service,@Repository等注解的类,都会加进来。
Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
Iterator var8 = scannedBeanDefinitions.iterator();
while(var8.hasNext()) {
BeanDefinitionHolder holder = (BeanDefinitionHolder)var8.next();
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
this.parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
//查询import导入的beanDefinition
this.processImports(configClass, sourceClass, this.getImports(sourceClass), filter, true);
importResource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
String[] var20 = resources;
int var22 = resources.length;
for(int var23 = 0; var23 < var22; ++var23) {
String resource = var20[var23];
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}
//查询@bean导入的beanDefinition
Set<MethodMetadata> beanMethods = this.retrieveBeanMethodMetadata(sourceClass);
Iterator var18 = beanMethods.iterator();
while(var18.hasNext()) {
MethodMetadata methodMetadata = (MethodMetadata)var18.next();
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
this.processInterfaces(configClass, sourceClass);
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
return sourceClass.getSuperClass();
}
}
return null;
}
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
//创建扫描器
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry, componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
//省略代码
//开始扫描,将扫描的BeanDefinitionHolder返回
return scanner.doScan(StringUtils.toStringArray(basePackages));
}
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
for (String basePackage : basePackages) {
// 找出当前包下面的所有符合条件的类,这个方法我们就不分析了。
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
// 处理一些其他情况,也不说了...
if (candidate instanceof AbstractBeanDefinition) {
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
// 最后注册BeanDefinition,这样就将包下的所有BeanDefintion都注册完成了
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
到这里为止,我们配置类的分析就结束了,将扫描的包下的BeanDefinition都注册完成了,接下来我们看下其它方式导入的beanDefinition的注册方法
this.reader.loadBeanDefinitions(configClasses);
private void loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
// 处理Imported的配置类
if (configClass.isImported()) {
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
// 注册所有的@Bean方法上的类,重点看一下这个方法
loadBeanDefinitionsForBeanMethod(beanMethod);
}
// 处理其它注解,这里就不分析了。
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
ConfigurationClass configClass = beanMethod.getConfigurationClass();
// 一些别名处理的代码都省略了...
// 创建BeanDefinition
ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata);
// 处理initMethod和destroyMethod
String initMethodName = bean.getString("initMethod");
if (StringUtils.hasText(initMethodName)) {
beanDef.setInitMethodName(initMethodName);
}
String destroyMethodName = bean.getString("destroyMethod");
beanDef.setDestroyMethodName(destroyMethodName);
// Replace the original bean definition with the target one, if necessary
BeanDefinition beanDefToRegister = beanDef;
// 最后注册这个BeanDefinition
this.registry.registerBeanDefinition(beanName, beanDefToRegister);
}
到这里,所有的beanDefinition全部注册完成
总结
spring 注册beanDefinition,首先是注册spring内部的bean,接着是注册我们编写的配置类,最后我们通过对配置类的扫描,加载扫描的所有beanDefinition。
我也是第一次写这么多东西,如果有哪些地方有问题,还希望跟各位多多交流。
网友评论