概述
一. 编译spring5源码
-
准备环境
- Idea: 2019.2.3
- gradle: 4.9 (idea的插件)
- Kotlin: 1.2.41(idea的插件,需要选择1.2后面有讲解)
- JVM: 1.8.0_131(我只用了这个版本,其他的没有用到,但是听他们说高版本的不好使)
-
安装gradle 4.9
2.1 官网地址https://downloads.gradle-dn.com/distributions/gradle-4.9-bin.zip
2.2 安装过程很简单,就是解压到非中文目录下,并配置环境变量
配置用户仓库和安装HOME
配置Path环境变量
2.3 更改gradle的下载镜像(改变为国内的阿里云镜像)
创建init.gradle文件
添加代码
allprojects{ repositories { def ALIYUN_REPOSITORY_URL = 'http://maven.aliyun.com/nexus/content/groups/public' def ALIYUN_JCENTER_URL = 'http://maven.aliyun.com/nexus/content/repositories/jcenter' all { ArtifactRepository repo -> if (repo instanceof MavenArtifactRepository) { def url = repo.url.toString() if (url.startsWith('https://repo1.maven.org/maven2')) { project.logger.lifecycle "Repository ${repo.url} replaced by $ALIYUN_REPOSITORY_URL." remove repo } if (url.startsWith('https://jcenter.bintray.com/')) { project.logger.lifecycle "Repository ${repo.url} replaced by $ALIYUN_JCENTER_URL." remove repo } } } maven { url ALIYUN_REPOSITORY_URL url ALIYUN_JCENTER_URL } } }
-
github上下载spring5.0.x源码
- 搜索spring-framework
- 选择版本号
-
下载
-
解压到你本地的idea的项目目录下
-
idea配置gradle(仅仅是选择用户目录就是GRADLE_USER_HOME这个位置)
-
通过idea打开spring-framework5.0.x
-
自动构建会出现问题
首先把gradle变为本地的gradle
修改其他的所有的配置文件
def deps = compileGroovy.taskDependencies.immutableValues + compileGroovy.taskDependencies.mutableValues
compileGroovy.dependsOn = deps - 'compileJava'
compileKotlin.dependsOn(compileGroovy)
compileKotlin.classpath += files(compileGroovy.destinationDir)
- 构建完成
二. 创建项目使用spring源码
- 选择项目添加module,选择gradle项目
-
项目一样会自动构建,构建完成后出现一下目录
-
需要引入spring框架源码
-
这样就能进行开发了
三. spring容器的整体架构
-
bean和对象的关系
bean 一定是一个对象
对象不一定是一个spring bean
spring bean必须是一个对象,必须经历一个完成的spring生命周期
-
spring容器架构图
-
spring容器的概念:
理念:各种spring组件的集合就是spring容器,这些组件包括BeanFactory,BeanFactoryPostProcesser…等等
Spring容器是生成Bean实例的工厂,并管理容器中的Bean。
代码层面:其实spring容器就是DefaultListableBeanFactory
- 对于常用的AnnotationConfigApplicationContext创建容器它的父类是GenericApplicationContext
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { //这里由于它具有父类,所以会先调用父类的构造方法,然后才会调用自己的构造方法 //在自己的构造方法中初始化一个读取器和扫描器 this(); //主要是两个作用1.把传递过来的类注册到容器中也就是map中 2.把spring自己的组件注册到其中 register(annotatedClasses); //这个是整个spring容器的核心 refresh(); } //它的父类的构造方法 /** * Create a new GenericApplicationContext. * @see #registerBeanDefinition * @see #refresh * 描述:当调用子类的构造方法之前,会先调用这人构造方法,就是初始化一个工厂 */ public GenericApplicationContext() { //这个类就是bean工厂代码级别的体现 this.beanFactory = new DefaultListableBeanFactory(); }
-
对于常用的ClassPathXmlApplicationContext是怎么创建BeanFactory的
//这个类创建的时候其实最终就是这样的 //参数说明:1.configLocations = new String[] {configLocation} 就是传递过来的配置文件 // 2.refresh //这个默认为true 表示是否刷新容器 // 3.parent //这个表示的是父容器 默认为空 public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException { //准备环境和调用父类的一些构造方法 super(parent); //把配置文件的路径梵高这个数组中private String[] configLocations; //具体操作 //转换路径 //this.configLocations[i] = resolvePath(locations[i]).trim(); // 抽象基类,用于根据任何基础源解析属性。AbstractPropertyResolver //org.springframework.core.env.AbstractPropertyResolver#doResolvePlaceholders //其实到后面就会发现其实就是里面为了转换资源占位符 ${} 并添加到数组中 setConfigLocations(configLocations); if (refresh) { //这个是整个spring最最重要的一个方法了 refresh(); } }
-
既然提到了常用类,就不得不说一下spring的核心类DefaultListableBeanFactory(这个就是咱们所说的bean工厂)
首先看一下他的继承类图
-
BeanFactory:这个类是整个spring工厂的最顶层接口,定义了一些获取bean的方法和是否单例、是否原型、是否存在、是否类型匹配、得到类型、得到所有的别名
-
ListableBeanFactory:提供各种条件获取bean的配置清单
//根据bean的名字判断,容器中是否存在这个Bean描述 boolean containsBeanDefinition(String beanName); //获得所有的bean描述 BeanDefinitionNames后面会介绍,其实就是对bean的描述 String[] getBeanDefinitionNames(); //容器中所有的bean描述的数量 int getBeanDefinitionCount(); //该方法用于获取 Spring 容器中指定类型的所有 JavaBean 的名称。 String[] getBeanNamesForType(@Nullable Class<?> type); //通过类型获取所有的bean集合 <T> Map<String, T> getBeansOfType(@Nullable Class<T> type); //通过注解获取该注解类型的所有bean的名称 String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType); //通过注解类型获取所有的bean集合 Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType); //在指定的bean上找到{@code annotationType}的{@link Annotation},如果在给定的类本身上找不到注释,则遍历它的接口和超类。 <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType);
-
AutowireCapableBeanFactory:提供创建bean(createBean)、自动注入(autowireBean)、配置给定的原始bean并自动装配bean的属性、初始化、应用bean的前后置处理器、销毁bean、resolveNamedBean、根据工厂中定义的bean解析指定的依赖项。
-
ConfigurableBeanFactory:提供配置bean的各种方法(方法实在是太多了,以后碰到的时候在具体解析)
String SCOPE_SINGLETON = "singleton"; String SCOPE_PROTOTYPE = "prototype"; void setParentBeanFactory(BeanFactory parentBeanFactory); void setBeanClassLoader(@Nullable ClassLoader beanClassLoader); ClassLoader getBeanClassLoader(); void setTempClassLoader(@Nullable ClassLoader tempClassLoader); ClassLoader getTempClassLoader(); void setCacheBeanMetadata(boolean cacheBeanMetadata); boolean isCacheBeanMetadata(); void setBeanExpressionResolver(@Nullable BeanExpressionResolver resolver); BeanExpressionResolver getBeanExpressionResolver(); void setConversionService(@Nullable ConversionService conversionService); ConversionService getConversionService(); void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar); void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass); void copyRegisteredEditorsTo(PropertyEditorRegistry registry); void setTypeConverter(TypeConverter typeConverter); TypeConverter getTypeConverter(); void addEmbeddedValueResolver(StringValueResolver valueResolver); boolean hasEmbeddedValueResolver(); String resolveEmbeddedValue(String value); void addBeanPostProcessor(BeanPostProcessor beanPostProcessor); int getBeanPostProcessorCount(); void registerScope(String scopeName, Scope scope); String[] getRegisteredScopeNames(); Scope getRegisteredScope(String scopeName); AccessControlContext getAccessControlContext(); void copyConfigurationFrom(ConfigurableBeanFactory otherFactory); void registerAlias(String beanName, String alias); void resolveAliases(StringValueResolver valueResolver); BeanDefinition getMergedBeanDefinition(String beanName); boolean isFactoryBean(String name); void setCurrentlyInCreation(String beanName, boolean inCreation); boolean isCurrentlyInCreation(String beanName); void registerDependentBean(String beanName, String dependentBeanName); String[] getDependentBeans(String beanName); String[] getDependenciesForBean(String beanName); void destroyBean(String beanName, Object beanInstance); void destroyScopedBean(String beanName); void destroySingletons();
-
AliasRegistry接口:提供一些对别名的操作注册,移除,判断,得到所有别名
-
SimpleAliasRegistry:实现了所有的AliasRegistry接口的方法、
//别名集合 这个后面也用到了,很重要的一个集合 private final Map<String, String> aliasMap = new ConcurrentHashMap<>(16); //自己的方法,返回是否允许别名覆盖。 protected boolean allowAliasOverriding() { return true; } //确定给定名称是否注册了给定别名。就是遍历这个map集合 public boolean hasAlias(String name, String alias){...} //重载的方法,返回这个集合 private void retrieveAliases(String name, List<String> result){...} //解析此工厂中注册的所有别名目标名和别名,并将给定的StringValueResolver应用于它们。 public void resolveAliases(StringValueResolver valueResolver){...} //确定原始名称,将别名解析为规范名称。 public String canonicalName(String name) {...} //检查给定名称是否已经指向另一个方向的给定别名作为别名,捕获循环引用并抛出相应Exception。 protected void checkForAliasCircle(String name, String alias){...}
-
DefaultSingletonBeanRegistry:它继承SimpleAliasRegistry类和实现了SingletonBeanRegistry接口,因此这个类可以有别名注册的功能和单例bean注册的功能
- 给BeanFactory的实现,提供基本的管理 singleton bean 实例功能。
- 是一个通用的存储共享bean实例的地方,通过bean的名字获得bean。同时,它也给提供一次性bean的注册功能。
- 这个类中,使用了三个主要的存储器(map)来分别存储 singletonObject,singletonFactory,earlySingletonObject。
/** 单例对象缓存:bean名称——> bean实例 */ private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); /** 单例工厂的缓存:bean名——> ObjectFactory */ private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); /** 早期单例对象的缓存:bean名称——> bean实例 */ private final Map<String, Object> earlySingletonObjects = new HashMap<>(16); /** 一组已注册的单例,包含按注册顺序排列的bean名称 */ private final Set<String> registeredSingletons = new LinkedHashSet<>(256); /** 当前正在创建的bean的名称 */ private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16)); /** 当前在创建检查中被排除在外的bean的名称 */ private final Set<String> inCreationCheckExclusions = Collections.newSetFromMap(new ConcurrentHashMap<>(16)); /** 被抑制的异常列表,可用于关联相关原因*/ @Nullable private Set<Exception> suppressedExceptions; /** 标志,指示我们当前是否在destroysingleton中 */ private boolean singletonsCurrentlyInDestruction = false; /** 一次性bean实例:bean名称——>一次性实例 */ private final Map<String, Object> disposableBeans = new LinkedHashMap<>(); /** 包含bean名称之间的映射:bean名称——bean所包含的bean名称的>集合 */ private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16); /** 依赖bean名称之间的映射:bean名称——依赖bean名称的>集合 */ private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64); /** bean名称之间的映射:bean名称——bean依赖项的> bean名称集 */ private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64); //下面是一些重要的方法,也就是这个类自带的 //添加指定的单例工厂来构建指定的单例如果有必要。其实就是添加到上面定义的map集合中 protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) //还有一些getSingleton的重写方法 //注册一个在创建一个单例bean实例时被抑制的异常,例如一个临时的循环引用解析问题。 protected void onSuppressedException(Exception ex) //设计目前正在创建的单例 public void setCurrentlyInCreation(String beanName, boolean inCreation) //是否正在创建isCurrentlyInCreation //是否现在创建isActuallyInCreation //下面是两个回调函数 //beforeSingletonCreation 单例创建之前 //afterSingletonCreation 单例创建之后 //注册包含bean public void registerContainedBean(String containedBeanName, String containingBeanName) //还有销毁bean 的方法 销毁单例 清空单例缓存池 得到所有依赖bean
-
FactoryBeanRegistrySupport:支持需要处理的单例注册表的基类
/** FactoryBean创建的单例对象的缓存:FactoryBean名称——>对象 */ private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16); //确定给定FactoryBean的类型。 protected Class<?> getTypeForFactoryBean(final FactoryBean<?> factoryBean) //获取要从给定FactoryBean公开的对象(如果以缓存形式可用)快速检查最小同步就是从map中获取 protected Object getCachedObjectForFactoryBean(String beanName){...} //获取要从给定的FactoryBean公开的对象。 //主要处理两个问题,第一个是工厂是不是单例的,第二个是这个Bean是否需要进一步处理 protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) //获取要从给定的FactoryBean公开的对象。 private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
-
AbstractBeanFactory:综合FactoryBeanRegistrySupport和ConfigurableBeanFactory的功能
/** 父bean工厂,用于bean继承支持 */ @Nullable private BeanFactory parentBeanFactory; /** 类装入器来解析bean类名(如果需要) */ @Nullable private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); /** 类装入器来临时解析bean类名(如果需要)*/ @Nullable private ClassLoader tempClassLoader; /** 是缓存bean元数据,还是为每次访问重新获取它*/ private boolean cacheBeanMetadata = true; /** bean定义值中的表达式的解析策略 */ @Nullable private BeanExpressionResolver beanExpressionResolver; /** 使用Spring ConversionService而不是propertyeditor */ @Nullable private ConversionService conversionService; /** 自定义属性编辑登记应用到工厂的bean */ private final Set<PropertyEditorRegistrar> propertyEditorRegistrars = new LinkedHashSet<>(4); /** 将自定义属性编辑器应用于此工厂的bean */ private final Map<Class<?>, Class<? extends PropertyEditor>> customEditors = new HashMap<>(4); /** 要使用的自定义类型转换器,覆盖默认的属性编辑器机制 */ @Nullable private TypeConverter typeConverter; /** 将例如应用于注释属性值的字符串解析器 */ private final List<StringValueResolver> embeddedValueResolvers = new CopyOnWriteArrayList<>(); /** 在createBean中应用的Bean后置处理器 */ private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>(); /** 指示是否注册了任何实例化awarebeanpostprocessor */ private volatile boolean hasInstantiationAwareBeanPostProcessors; /** 从范围标识符字符串映射到相应的范围 */ private final Map<String, Scope> scopes = new LinkedHashMap<>(8); /** 使用SecurityManager运行时使用的安全上下文 */ @Nullable private SecurityContextProvider securityContextProvider; /** 从bean名称映射到合并的RootBeanDefinition */ private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256); /** 至少已经创建过一次的bean的名称 */ private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256)); /** 当前正在创建的bean的名称 */ private final ThreadLocal<Object> prototypesCurrentlyInCreation = new NamedThreadLocal<>("Prototype beans currently in creation"); //提供了几个getBean方法,但是都是一行代码都是进行doGetBean //接下来这个是最重要的方法了 返回指定bean的一个实例,该实例可以是共享的,也可以是独立的。 //后面简介创建bean的时候在进行解析 protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,@Nullable final Object[] args, boolean typeCheckOnly);
-
ConfigurableListableBeanFactory:BeanFactory配置清单指定忽略类型以及接口等
-
AbstractAutowireCapableBeanFactory:综合AbstractBeanFactory并对接口AutowriteCapableBeanFactory进行实现
-
DefaultListableBeanFactory 综合以上所有功能,主要是bean注册后的处理
-
-
四. 常用的spring容器创建
-
AnnotationConfigApplicationContext:这个类主要是在创建的时候,调用父类GenericApplicationContext的构造方法进行创建的bean工厂
public GenericApplicationContext() { //这个类就是bean工厂代码级别的体现 this.beanFactory = new DefaultListableBeanFactory(); }
-
ClassPathXmlApplicationContext:创建的流程
AbstractApplicationContext:
refresh()——>obtainFreshBeanFactory()——>refreshBeanFactory();
org.springframework.context.support.AbstractRefreshableApplicationContext#refreshBeanFactory
@Override protected final void refreshBeanFactory() throws BeansException { //如果已经存在工厂的话,就销毁之前的工厂,并关闭这个工厂 if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { //这个才是创建bean工厂 DefaultListableBeanFactory beanFactory = createBeanFactory(); //设置id beanFactory.setSerializationId(getId()); customizeBeanFactory(beanFactory); //解析标签 loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }
五. xml文件解析
1. 方法路径
AbstractApplicationContext#refresh——>AbstractApplicationContext#obtainFreshBeanFactory
——>AbstractRefreshableApplicationContext#refreshBeanFactory——>loadBeanDefinitions(beanFactory);
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// 为给定的BeanFactory创建一个新的XmlBeanDefinitionReader。
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// Configure the bean definition reader with this context's
// resource loading environment.
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// Allow a subclass to provide custom initialization of the reader,
// then proceed with actually loading the bean definitions.
initBeanDefinitionReader(beanDefinitionReader);
//这个才是真正的解析xml 前面的都是准备的一些环境啥的
loadBeanDefinitions(beanDefinitionReader);
}
2. XmlBeanDefinitionReader
还是先看类图吧
-
BeanDefinitionReader:主要定义资源文件读取并转换为BeanDefinition的各个功能
//返回bean工厂来注册bean定义。 BeanDefinitionRegistry getRegistry(); //返回用于资源位置的资源加载程序 ResourceLoader getResourceLoader(); //返回用于bean类的类装入器。 ClassLoader getBeanClassLoader(); //返回用于匿名bean的BeanNameGenerator BeanNameGenerator getBeanNameGenerator(); //从指定资源加载bean定义。 int loadBeanDefinitions(Resource resource)
-
AbstractBeanDefinitionReader:对实现的两个接口功能进行实现
-
DefaultBeanDefinitionDocumentReader类解析
//bean public static final String BEAN_ELEMENT = BeanDefinitionParserDelegate.BEAN_ELEMENT; public static final String NESTED_BEANS_ELEMENT = "beans"; public static final String ALIAS_ELEMENT = "alias"; public static final String NAME_ATTRIBUTE = "name"; public static final String ALIAS_ATTRIBUTE = "alias"; public static final String IMPORT_ELEMENT = "import"; public static final String RESOURCE_ATTRIBUTE = "resource"; public static final String PROFILE_ATTRIBUTE = "profile"; //解释器委派 private BeanDefinitionParserDelegate delegate;
3. loadBeanDefinitions***
//得到本地配置文件,并进行下一步的解析
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
//获取本地配置文件
String[] configLocations = getConfigLocations();
if (configLocations != null) {
//这里才是真正的加载,通过reader 继续向下走
reader.loadBeanDefinitions(configLocations);
}
}
@Override
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
Assert.notNull(locations, "Location array must not be null");
int counter = 0;
for (String location : locations) {
//主要是这里进行解析
counter += loadBeanDefinitions(location);
}
return counter;
}
public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
//得到资源加载器
ResourceLoader resourceLoader = getResourceLoader();
if (resourceLoader == null) {
throw new BeanDefinitionStoreException(
"Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
}
if (resourceLoader instanceof ResourcePatternResolver) {
// Resource pattern matching available.
try {
Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
//然后这里才是真正的解析标签
int loadCount = loadBeanDefinitions(resources);
。。。
}
}
}
//下面XmlBeanDefinitionReader#loadBeanDefinitions——>doLoadBeanDefinitions
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
//获取document
Document doc = doLoadDocument(inputSource, resource);
//这里才是核心逻辑部分m接下来进入到里面进行分析
return registerBeanDefinitions(doc, resource);
}
catch (Exception ex) {
throw ex;
}
}
}
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
//创建DefaultBeanDefinitionDocumentReader 这个类上面介绍了
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
//获取统计前工厂里面所有的bean描述
int countBefore = getRegistry().getBeanDefinitionCount();
//开始进行获取,继续向下走
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
logger.debug("Loading bean definitions");
Element root = doc.getDocumentElement();
//这里是核心代码逻辑,进去瞧一瞧
doRegisterBeanDefinitions(root);
}
protected void doRegisterBeanDefinitions(Element root) {
BeanDefinitionParserDelegate parent = this.delegate;
this.delegate = createDelegate(getReaderContext(), root, parent);
if (this.delegate.isDefaultNamespace(root)) {
//先解析profiles属性
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
if (StringUtils.hasText(profileSpec)) {
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
if (logger.isInfoEnabled()) {
logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec +
"] not matching: " + getReaderContext().getResource());
}
return;
}
}
}
//解析xml之前执行的操作,空方法估计是以后会用到吧
preProcessXml(root);
//真正的解析,进去看看
parseBeanDefinitions(root, this.delegate);
//解析之后执行的操作
postProcessXml(root);
this.delegate = parent;
}
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
//循环处理
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
//对bean处理,这个才是真正的处理
parseDefaultElement(ele, delegate);
}
else {
//对bean处理
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
六. 默认标签的解析(Bean)
1. 默认标签的解析parseDefaultElement(…)
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
//解析import标签
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
//解析alias标签
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
//bean标签的处理,接下来进入这个方法
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);
}
//beans标签的处理
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse
doRegisterBeanDefinitions(ele);
}
}
2. bean标签的解析processBeanDefinition(…)
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate){
//委派方法进行元素解析 返回dnHolder实例,已经包含了我们配置文件中的各种属性
//我们进去这个方法看一下
//他会走i到他重载的两个参数的方法
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
//解析提供的{@code <bean>}元素。可能返回{@code null} 其实返回的就是BeanDefinitionHolder
//首先是提取了一些id name属性
//进一步解析其他的所有属性 beanName别设置为了解析出来的id
//parseBeanDefinitionElement(ele, beanName, containingBean);主要的方法
//进一步解析出其他的属性并统一封装到GenericBeanDefinition类型中
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
//解析id属性
String id = ele.getAttribute(ID_ATTRIBUTE);
//解析name属性
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
//别名集合
List<String> aliases = new ArrayList<>();
//判断name是否不为空
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
//放到别名集合中,其实就是起别名
aliases.addAll(Arrays.asList(nameArr));
}
//让id变成beanName属性
String beanName = id;
if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
beanName = aliases.remove(0);
if (logger.isDebugEnabled()) {
logger.debug("No XML 'id' specified - using '" + beanName +
"' as bean name and " + aliases + " as aliases");
}
}
if (containingBean == null) {
checkNameUniqueness(beanName, aliases, ele);
}
//这里是重点,主要是创建GenericBeanDefinition
//并统一封装其他的属性
//如果没有beanName属性 将会使用默认规则为此Bean生成beanName
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
if (beanDefinition != null) {
if (!StringUtils.hasText(beanName)) {
try {
if (containingBean != null) {
beanName = BeanDefinitionReaderUtils.generateBeanName(
beanDefinition, this.readerContext.getRegistry(), true);
}
else {
beanName = this.readerContext.generateBeanName(beanDefinition);
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName != null &&
beanName.startsWith(beanClassName) &&
beanName.length() > beanClassName.length() &&
!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
aliases.add(beanClassName);
}
}
if (logger.isDebugEnabled()) {
logger.debug("Neither XML 'id' nor 'name' specified - " +
"using generated bean name [" + beanName + "]");
}
}
catch (Exception ex) {
error(ex.getMessage(), ele);
return null;
}
}
String[] aliasesArray = StringUtils.toStringArray(aliases);
//封装成BeanDefinitionHolder对象进行返回
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
}
return null;
}
}
//解析各种属性 并封装到GenericBeanDefinition类中
public AbstractBeanDefinition parseBeanDefinitionElement(
Element ele, String beanName, @Nullable BeanDefinition containingBean) {
this.parseState.push(new BeanEntry(beanName));
String className = null;
//解析class属性
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
}
String parent = null;
//解析parent属性
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
try {
//创建用于承载属性的AbstractBeanDefinition类型的GenericBeanDefinition 并且已经设置了parentname和class路径
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
//解析bean标签的所有的默认属性,并且为bd设置一些默认值,源码其实很简单,所以就不看了
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
//设置描述,解释bean标签下的子标签<description></description>
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
//解析元数据 解释解析bean标签下的meta标签
parseMetaElements(ele, bd);
//解析bean标签下的lookup-method标签
//这里说一下lookup-method标签的作用吧
//假设一个单例模式的bean A需要引用另外一个非单例模式的bean B,为了在我们每次引用的时候都能拿到最新的bean B
/**
* // 定义一个水果类
* public class Fruit {
* public Fruit() {
* System.out.println("I got Fruit");
* }
* }
*
* // 苹果
* public class Apple extends Fruit {
* public Apple() {
* System.out.println("I got a fresh apple");
* }
* }
*
* // 香蕉
* public class Bananer extends Fruit {
* public Bananer () {
* System.out.println("I got a fresh bananer");
* }
* }
*
* // 水果盘,可以拿到水果
* public abstract class FruitPlate{
* // 抽象方法获取新鲜水果
* protected abstract Fruit getFruit();
* }
* <!-- 这是2个非单例模式的bean -->
* <bean id="apple" class="cn.com.willchen.test.di.Apple" scope="prototype"/>
* <bean id="bananer" class="cn.com.willchen.test.di.Bananer " scope="prototype"/>
*
* <bean id="fruitPlate1" class="cn.com.willchen.test.di.FruitPlate">
* <lookup-method name="getFruit" bean="apple"/>
* </bean>
* <bean id="fruitPlate2" class="cn.com.willchen.test.di.FruitPlate">
* <lookup-method name="getFruit" bean="bananer"/>
* </bean>
*/
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
//解析replaced-method标签
//作用:方法替换,可以在运行时用心的方法替换现有的方法
//其实就是说当你想把一个bean里面某个方法替换成别的方法的时候就能使用这个标签了
//你需要创建一个类并且实现MethodReplacer这个接口
//然后就会被替换了
/**
* <bean id="example2" class="com.shy.spring.beans.Example2">
* <meta key="key" value="value"/>
* <replaced-method name="setData" replacer="replacer" />
* </bean>
* <bean id="replacer" class="com.shy.spring.factoryconfig.MyMethodReplacer"/>
* 描述:这个是将要替换成的方法
* public class MyMethodReplacer implements MethodReplacer {
* @Override
* public Object reimplement(Object obj, Method method, Object[] args) throws * Throwable {
* System.out.println(obj);
* System.out.println(method.getName());
* System.out.println(args);
* return obj;
* }
* }
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
//解析构造函数参数,其实这个挺重要的就是constructor-arg这个标签
//它里面的处理其实挺有意思的 会判断各种类型
parseConstructorArgElements(ele, bd);
//解析property标签 其实这个是最常用的
parsePropertyElements(ele, bd);
//解析qualifier子标签 其实他就类似于注解@Qualifier
//消除歧义,因为当自动注入的时候Bean的数目必须有且仅有一个,当找不到一个的时候将会抛出异常BeanCreationException异常
//指定注入的bean的名称
parseQualifierElements(ele, bd);
bd.setResource(this.readerContext.getResource());
bd.setSource(extractSource(ele));
return bd;
}
}
七. 属性承载的BeanDefinition
7.1 类图
BeanDefinition
继承了AttributeAccessor
和BeanMetadataElement
接口。在Spring中充斥着大量的各种接口,每种接口都拥有不同的能力,某个类实现了某个接口,也就相应的拥有了某种能力。
概念:在Java中,一切皆对象。在JDK中使用java.lang.Class
来描述类
这个对象。
在Spring中,存在bean
这样一个概念,那Spring又是怎么抽象bean
这个概念,用什么类来描述bean
这个对象呢?Spring使用BeanDefinition
来描述bean
。
7.2 AttributeAccessor
顾名思义,这是一个属性访问者,它提供了访问属性的能力。
7.3 BeanMetadataElement
BeanMetadataElement
中只有一个方法,用来获取元数据元素的配置源对象:
7.4 BeanDefinition
BeanDefinition
接口是Spring对bean
的抽象。
我们可以从源码中可以看出,Spring是怎么描述一个bean
:
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
/**
* 标准单例范围的范围标识符:“单例”。
*/
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
/**
* 标准原型范围的范围标识符:“原型”。
*/
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
/**
* 表示{@code BeanDefinition}是主要部分的角色提示
*/
int ROLE_APPLICATION = 0;
/**
* 角色提示,指示{@code BeanDefinition}是某些较大配置(通常是外部配置)的支持部分
*/
int ROLE_SUPPORT = 1;
/**
* 角色提示,指示{@code BeanDefinition}提供完全的后台角色,与最终用户无关。此提示用于注册完全属 * 于{@link org.springframework.bean .factory. parsing.componentdefinition}内部工作的一 * 部分的bean。
*/
int ROLE_INFRASTRUCTURE = 2;
// 改变属性
/**
* 设置此bean定义的父定义的名称(如果有的话)。
*/
void setParentName(@Nullable String parentName);
/**
* 如果有的话,返回这个bean定义的父定义的名称。
*/
@Nullable
String getParentName();
/**
* 指定此bean定义的bean类名。
*/
void setBeanClassName(@Nullable String beanClassName);
/**
* 返回此bean定义的当前bean类名。
*/
@Nullable
String getBeanClassName();
/**
* 覆盖此bean的目标范围,并指定新的范围名称。
*/
void setScope(@Nullable String scope);
/**
* 返回此bean的当前目标范围。
*/
@Nullable
String getScope();
/**
* 设置此bean是否应延迟初始化。
*/
void setLazyInit(boolean lazyInit);
/**
* 返回该bean是否应该延迟初始化,即在启动时不急于实例化。仅适用于单例bean。
*/
boolean isLazyInit();
/**
* 设置此bean依赖于被初始化的bean的名称。bean工厂将确保首先初始化这些bean。
*/
void setDependsOn(@Nullable String... dependsOn);
/**
* 返回此bean所依赖的bean名称。
*/
@Nullable
String[] getDependsOn();
/**
* 设置这个bean是否可以被其他bean自动捕获。
*/
void setAutowireCandidate(boolean autowireCandidate);
/**
* 返回该bean是否可以被自动装配到其他bean中。
*/
boolean isAutowireCandidate();
/**
* 设置此bean是否是主要的自动装配候选。
*/
void setPrimary(boolean primary);
/**
* 返回此bean是否是主要的自动装配候选。
*/
boolean isPrimary();
/**
* 指定要使用的工厂bean(如果有的话)。
*/
void setFactoryBeanName(@Nullable String factoryBeanName);
/**
* 返回工厂bean名(如果有的话)。
*/
@Nullable
String getFactoryBeanName();
/**
* 指定工厂方法(如果有的话)。此方法将使用构造函数参数调用,如果未指定参数,则不使用参数调用。该方法将在指定的工厂bean(如果有的话)上调用,或者作为本地bean类的静态方法调用。
*/
void setFactoryMethodName(@Nullable String factoryMethodName);
/**
* 返回工厂方法(如果有的话)。
*/
@Nullable
String getFactoryMethodName();
/**
* 返回此bean的构造函数参数值。
*/
ConstructorArgumentValues getConstructorArgumentValues();
/**
* 如果有为这个bean定义的构造函数参数值,则返回。
* @since 5.0.2
*/
default boolean hasConstructorArgumentValues() {
return !getConstructorArgumentValues().isEmpty();
}
/**
* 返回要应用到bean的新实例的属性值。
* 返回的实例可以在bean工厂的后处理过程中修改。
*/
MutablePropertyValues getPropertyValues();
/**
* 如果有为这个bean定义的属性值,则返回。
* @since 5.0.2
*/
default boolean hasPropertyValues() {
return !getPropertyValues().isEmpty();
}
// 只读属性
/**
* 返回此单例是否具有单个共享实例
*/
boolean isSingleton();
/**
* 返回这个原型,每个调用返回一个独立的实例。
* @since 3.0
* @see #SCOPE_PROTOTYPE
*/
boolean isPrototype();
/**
* 返回这个bean是否“抽象”,也就是说,它不是要实例化的。
*/
boolean isAbstract();
/**
* 获取这个BeanDefinition的角色提示。框架和工具提供指示一个特定的BeanDefinition的作用和重要性。
* @see #ROLE_APPLICATION
* @see #ROLE_SUPPORT
* @see #ROLE_INFRASTRUCTURE
*/
int getRole();
/**
* 返回该bean定义的可读描述。
*/
@Nullable
String getDescription();
/**
* 返回此bean定义来自的资源的描述(用于在出现错误时显示上下文)。
*/
@Nullable
String getResourceDescription();
/**
* 返回原始的BeanDefinition,如果没有,则返回null允许检索修饰过的bean定义(如果有的话)。
*/
@Nullable
BeanDefinition getOriginatingBeanDefinition();
}
7.5AnnotatedBeanDefinition
AnnotatedBeanDefinition
继承了BeanDefinition
,拓展了BeanDefinition
接口的能力:
7.6BeanDefinition常见实现类
- ChildBeanDefinition
- RootBeanDefinition
- GenericBeanDefinition
- AnnotatedGenericBeanDefinition
- ScannedGenericBeanDefinition
7.7 BeanDefinitionBuilder
BeanDefinitionBuilder
是Builder模式的应用。通过这个类我们可以方便的构建BeanDefinition
的实例对象。举个例子:
BeanDefinitionRegistryPostProcessor
继承了BeanFactoryPostProcessor
接口,同时又增加了一个新的方法BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
,该方法允许程序员通过代码编码的方式手动往程序中注册BeanDefinition
。
/**
* @author 石皓岩
* @create 2020-01-21 20:57
* 描述:能够让程序员在代码运行阶段自己创建一个BeanDefinition
*/
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
throws BeansException {
BeanDefinition beanDefinition = null;
BeanDefinitionBuilder.genericBeanDefinition(CityService.class)
//这里的属性名是根据setter方法
.addPropertyReference("cityService", "cityService")
.setInitMethodName("init")
.setScope(BeanDefinition.SCOPE_SINGLETON)
.getBeanDefinition();
registry.registerBeanDefinition("testService", beanDefinition);
}
//这个是父接口的方法,其实就是运行期间可以更改一个BeanDefinition的各种属性,这个其实挺重要的,
//程序员能影响工厂构建过程
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
7.8 AbstractBeanDefinition
AbstractBeanDefinition
实现了BeanDefinition
定义的一系列操作,定义了描述Bean画像的一系列属性,在AbstractBeanDefinition
的基础上,Spring
衍生出了一系列具有特殊用途的BeanDefinition
。
//默认范围 “单例”
public static final String SCOPE_DEFAULT = "";
/**
* 常量,表示根本没有外部自动装配。
* @see #setAutowireMode
*/
public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO;
/**
* 常量,该常量通过名称指示自动装配bean属性。
* @see #setAutowireMode
*/
public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
/**
* 常量,该常量根据类型指示自动装配bean属性。
* @see #setAutowireMode
*/
public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
/**
* 表示自动装配构造函数的常量。
* @see #setAutowireMode
*/
public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;
/**
* 常量,指示通过bean类的内省确定适当的自动装配策略。
*/
@Deprecated
public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;
/**
* 常量,表示根本没有依赖项检查。
*/
public static final int DEPENDENCY_CHECK_NONE = 0;
/**
* 常量,指示对象引用的依赖项检查。
* @see #setDependencyCheck
*/
public static final int DEPENDENCY_CHECK_OBJECTS = 1;
/**
* 常量,指示“简单”属性的依赖项检查。
*/
public static final int DEPENDENCY_CHECK_SIMPLE = 2;
/**
* 常量,指示所有属性的依赖项检查
* (object references as well as "simple" properties).
* @see #setDependencyCheck
*/
public static final int DEPENDENCY_CHECK_ALL = 3;
/**
* Constant that indicates the container should attempt to infer the
* {@link #setDestroyMethodName destroy method name} for a bean as opposed to
* explicit specification of a method name. The value {@value} is specifically
* designed to include characters otherwise illegal in a method name, ensuring
* no possibility of collisions with legitimately named methods having the same
* name.
* <p>Currently, the method names detected during destroy method inference
* are "close" and "shutdown", if present on the specific bean class.
*/
public static final String INFER_METHOD = "(inferred)";
@Nullable
private volatile Object beanClass;
//bean的作用范围,对应bean属性scope
@Nullable
private String scope = SCOPE_DEFAULT;
//是否抽象
private boolean abstractFlag = false;
//是否懒加载
private boolean lazyInit = false;
//自动注入模式,对应bean属性autowrie
private int autowireMode = AUTOWIRE_NO;
//依赖检查,后面弃用了这个属性
private int dependencyCheck = DEPENDENCY_CHECK_NONE;
//用来表示一个bean的实例化依靠另一个bean先实例化,对应bean的属性depend-on
@Nullable
private String[] dependsOn;
//当它是false的时候,他将不会自动装配到其他的bean上 但是他自己是运行进行自动装配的
private boolean autowireCandidate = true;
//自动装配时出现多个bean候选者时,将作为首选者,对应bean属性primary
private boolean primary = false;
//用于记录qualifiers
private final Map<String, AutowireCandidateQualifier> qualifiers = new LinkedHashMap<>();
//
@Nullable
private Supplier<?> instanceSupplier;
//允许访问非公开的构造器和方法,程序设置
private boolean nonPublicAccessAllowed = true;
//
private boolean lenientConstructorResolution = true;
//工厂bean名称
@Nullable
private String factoryBeanName;
//工厂方法名
@Nullable
private String factoryMethodName;
//记录构造函数注入属性
@Nullable
private ConstructorArgumentValues constructorArgumentValues;
//普通属性集合
@Nullable
private MutablePropertyValues propertyValues;
//方法重写的持有者,记录lookup-method,replaced-method元素
private MethodOverrides methodOverrides = new MethodOverrides();
//初始化方法 对应bean属性init-method
@Nullable
private String initMethodName;
//销毁方法 对应属性 destory-method
@Nullable
private String destroyMethodName;
//是否执行init-method
private boolean enforceInitMethod = true;
//是否执行destory-method
private boolean enforceDestroyMethod = true;
//创建aop的时候为true 是否是用户定义的而不是应用程序本身定义的
private boolean synthetic = false;
private int role = BeanDefinition.ROLE_APPLICATION;
//bean的描述信息
@Nullable
private String description;
//bean定义的资源
@Nullable
private Resource resource;
7.9 GenericBeanDefinition
是2.5版本以后加入的bean文件配置属性定义类,是一站式服务类。
在配置文件中可以定义父和子,父就用RootBeanDefinition,子就用ChildBeanDefinition。
spring通过BeanDefinition将配置文件中的信息转换为容器的内部表示,并将这些BeanDefinition注册到BeanDefinitionRegister中。spring容器的BeanDefinitionRegister就像是spring配置信息的内存数据库,主要是一map形式保存,后续操作直接从BeanDefinitionRegister中读取配置信息。
八. 解析默认标签中的自定义标签
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
//这里就是解析bean的各种属性 返回bdh就已经包含了 各种属性了
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
//当不为空的情况下,若存在默认标签解析
//接下来将要重点讲解这个方法
//如果需要就对BeanDefinition进行装饰
//其实它是适用这样的场景
/*<bean id="example2" class="com.shy.spring.beans.Example2">
<mybean:user username="" />
</bean>
*/
//解析来进行这个方法进行分析
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
public BeanDefinitionHolder decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder originalDef) {
//这里将第三个参数设置为空
//其实第三个参数是父类bean,当对某个嵌套配置进行分析时,这里需要传递父类beanDefinition
//传递参数就是为了使用父类的scope属性
//当防止子类没有设置这个属性的时候,默认使用父类的属性
return decorateBeanDefinitionIfRequired(ele, originalDef, null);
}
public BeanDefinitionHolder decorateBeanDefinitionIfRequired(
Element ele,
BeanDefinitionHolder originalDef,
@Nullable BeanDefinition containingBd) {
BeanDefinitionHolder finalDefinition = originalDef;
// Decorate based on custom attributes first.
NamedNodeMap attributes = ele.getAttributes();
//遍历所有的属性,看看是否有适用于修饰的属性
for (int i = 0; i < attributes.getLength(); i++) {
Node node = attributes.item(i);
finalDefinition = decorateIfRequired(node, finalDefinition, containingBd);
}
// Decorate based on custom nested elements.
NodeList children = ele.getChildNodes();
//遍历所有子节点,看看是否有适用于修饰的子元素
for (int i = 0; i < children.getLength(); i++) {
Node node = children.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
finalDefinition = decorateIfRequired(node, finalDefinition, containingBd);
}
}
return finalDefinition;
}
public BeanDefinitionHolder decorateIfRequired(
Node node, BeanDefinitionHolder originalDef, @Nullable BeanDefinition containingBd) {
//获得自定义标签的命名空间
String namespaceUri = getNamespaceURI(node);
//对于非默认标签进行修饰
if (namespaceUri != null && !isDefaultNamespace(namespaceUri)) {
//根据命名空间找到对应的处理器
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler != null) {
BeanDefinitionHolder decorated =
handler.decorate(node, originalDef, new ParserContext(this.readerContext, this, containingBd));
if (decorated != null) {
return decorated;
}
}
else if (namespaceUri.startsWith("http://www.springframework.org/")) {
error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", node);
}
else {
// A custom namespace, not to be handled by Spring - maybe "xml:...".
if (logger.isDebugEnabled()) {
logger.debug("No Spring NamespaceHandler found for XML schema namespace [" + namespaceUri + "]");
}
}
}
return originalDef;
}
九. 注册解析的BeanDefinition
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
//这里就是解析bean的各种属性 返回bdh就已经包含了 各种属性了
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
//当不为空的情况下,若存在默认标签解析
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// 注册BeanDefinition
// 很重要,接下来将看这个代码
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// 使用beanName做唯一标识注册
String beanName = definitionHolder.getBeanName();
// 这里开始进行注册
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// 为bean名称注册别名(如果有)。
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
9.1 通过BeanName注册beanDefinition
@Override
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是否与工厂并存或者mthodOberrides对应的方法根本不存在
*/
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
//如果对应的beanName已经注册且在配置了bean不允许被覆盖,则抛出异常
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
"': There is already [" + existingDefinition + "] bound.");
}
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isWarnEnabled()) {
logger.warn("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.isInfoEnabled()) {
logger.info("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
if (this.manualSingletonNames.contains(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
}
else {
//仍在启动注册阶段
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
//重置所有beanName缓存
resetBeanDefinition(beanName);
}
}
二.BeanDefintion解析及注册(注解)
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//这里由于它具有父类,所以会先调用父类的构造方法,然后才会调用自己的构造方法
//在自己的构造方法中初始化一个读取器和扫描器
/**
* Create a new GenericApplicationContext.
* @see #registerBeanDefinition
* @see #refresh
* 描述:当调用子类的构造方法之前,会先调用这人构造方法,就是初始化一个工厂
*/
/*public GenericApplicationContext() {
//这个类就是bean工厂代码级别的体现
this.beanFactory = new DefaultListableBeanFactory();
}*/
//这个this就是创建
/*public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}*/
this();
//主要是两个作用1.把传递过来的类注册到容器中也就是map中 2.把spring自己的组件注册到其中
//接下来先看一下这个
register(annotatedClasses);
refresh();
}
//register主要是AnnotatedBeanDefinitionReader#doRegisterBean方法起作用
<T> void doRegisterBean(Class<T> annotatedClass,
@Nullable Supplier<T> instanceSupplier,
@Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
//这个其实就是创建一个承载Bean的类,类似于之前xml方式创建的GenericBeanDefinition
//他们的继承和实现关系之前已经说过了
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(instanceSupplier);
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
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));
}
}
}
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
customizer.customize(abd);
}
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
一.spring本身BeanDefinition
public AnnotationConfigApplicationContext() {
//接下来将要介绍一下这个类
//容器加载Bean定义信息
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
//通过一系列的构造方法最终会走到这里
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);
}
//接下来通过一系列的方法会走到下面的方法
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
//这个方法就是把当前传递过来的BeanDefinitionRegistry转换为DefaultListableBeanFactory
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());
}
}
//BeanDefinitionHolder
//其实这个类就相当于一个map一样,他里面主要是有三个属性BeanDefinition 和beanName alias
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
//接下来就是注册spring本身需要的BeanDefinition
//org.springframework.context.annotation.internalConfigurationAnnotationProcessor
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
//这里才是真的关键registerPostProcessor(...)
//接下来将进入这个代码分析一下,怎么进行注册的
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
//org.springframework.context.annotation.internalAutowiredAnnotationProcessor
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));
}
//org.springframework.context.annotation.internalRequiredAnnotationProcessor
if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 检查是否支持JSR-250,如果支持,则添加CommonAnnotationBeanPostProcessor
//org.springframework.context.annotation.internalCommonAnnotationProcessor
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));
}
// 检查JPA支持,如果存在,添加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));
}
//org.springframework.context.event.internalEventListenerProcessor
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));
}
//org.springframework.context.event.internalEventListenerFactory
//至此所有的内部需要加载类都注册完毕
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;
}
//看一看spring容器是怎么注册本身的组件的
private static BeanDefinitionHolder registerPostProcessor(
BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
//设置一些权限。这个不用管
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//这个才是真的注册,他会直接AnnotationConfigApplicationContext父类的方法
//当时最终他会调用默认工厂DefaultListableBeanFactory里面的方法,接下来进去看看
registry.registerBeanDefinition(beanName, definition);
return new BeanDefinitionHolder(definition, beanName);
}
//这个方法之前已经提到过了,就是进行一些验证,最后最重要的就是把beanName和BeanDefinition放到集合中
//beanDefinitionMap
//this.beanDefinitionMap.put(beanName, beanDefinition);
//this.beanDefinitionNames.add(beanName);
//this.manualSingletonNames.remove(beanName);
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是否与工厂并存或者mthodOberrides对应的方法根本不存在
*/
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
"': There is already [" + existingDefinition + "] bound.");
}
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isWarnEnabled()) {
logger.warn("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.isInfoEnabled()) {
logger.info("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
if (this.manualSingletonNames.contains(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
}
else {
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
//这个是重制缓存
resetBeanDefinition(beanName);
}
}
二.注册传递过来的配置类
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//这里由于它具有父类,所以会先调用父类的构造方法,然后才会调用自己的构造方法
//在自己的构造方法中初始化一个读取器和扫描器
this();
//主要是两个作用1.把传递过来的类注册到容器中也就是map中
//接下来解析这个方法
register(annotatedClasses);
refresh();
}
//最主要的就是doRegisterBean方法
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
/**
* public AnnotatedGenericBeanDefinition(Class<?> beanClass) {
setBeanClass(beanClass);
this.metadata = new StandardAnnotationMetadata(beanClass, true);
}
*/
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
//设置创建实例的工厂
abd.setInstanceSupplier(instanceSupplier);
//单例的元数据
//这里会解析@Scpoe注解
//里面其实挺简单的,就是通过@Scpoe注解得到有哪些属性
//然后分别为属性重新设置Scope设置一下就行了
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
//这个需要着重介绍一下,他会生成一个默认的beanName
//后面介绍完注册成功自定义的配置类的时候会说一下这个
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//这个方法是解析公共注解标签
//说一下一共解析了多少个注解
//@Lazy
//@Primary
//@DependsOn
//@Role
//@Description
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));
}
}
}
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
customizer.customize(abd);
}
//这个已经介绍过了,相当于一个map不过只能存放一个key
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
//开始进行注册,和之前的就没有什么区别了,接下来的代码就是注册
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// 使用beanName做唯一标识注册
String beanName = definitionHolder.getBeanName();
// 这里开始进行注册
//最终都会执行DefaultListableBeanFactory
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// 为bean名称注册别名(如果有)。
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
三.关于beanName的生成策略
private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
public class AnnotationBeanNameGenerator implements BeanNameGenerator {
private static final String COMPONENT_ANNOTATION_CLASSNAME = "org.springframework.stereotype.Component";
//这个方法才是最重要的
@Override
public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
if (definition instanceof AnnotatedBeanDefinition) {
//从注解中确定BeanName
String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);
if (StringUtils.hasText(beanName)) {
// Explicit bean name found.
return beanName;
}
}
// Fallback: generate a unique default bean name.
//这里才是创建默认beanName的规则
/*
protected String buildDefaultBeanName(BeanDefinition definition) {
String beanClassName = definition.getBeanClassName();
Assert.state(beanClassName != null, "No bean class name set");
String shortClassName = ClassUtils.getShortName(beanClassName);
//这里就是把类名的首字母小写,里面的转换其实挺简单的
return Introspector.decapitalize(shortClassName);
}
*/
return buildDefaultBeanName(definition, registry);
}
/**
* Derive a bean name from one of the annotations on the class.
* @param annotatedDef the annotation-aware bean definition
* @return the bean name, or {@code null} if none is found
*/
@Nullable
protected String determineBeanNameFromAnnotation(AnnotatedBeanDefinition annotatedDef) {
AnnotationMetadata amd = annotatedDef.getMetadata();
Set<String> types = amd.getAnnotationTypes();
String beanName = null;
for (String type : types) {
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(amd, type);
if (attributes != null && isStereotypeWithNameValue(type, amd.getMetaAnnotationTypes(type), attributes)) {
Object value = attributes.get("value");
if (value instanceof String) {
String strVal = (String) value;
if (StringUtils.hasLength(strVal)) {
if (beanName != null && !strVal.equals(beanName)) {
throw new IllegalStateException("Stereotype annotations suggest inconsistent " +
"component names: '" + beanName + "' versus '" + strVal + "'");
}
beanName = strVal;
}
}
}
}
return beanName;
}
/**
* Check whether the given annotation is a stereotype that is allowed
* to suggest a component name through its annotation {@code value()}.
* @param annotationType the name of the annotation class to check
* @param metaAnnotationTypes the names of meta-annotations on the given annotation
* @param attributes the map of attributes for the given annotation
* @return whether the annotation qualifies as a stereotype with component name
*/
protected boolean isStereotypeWithNameValue(String annotationType,
Set<String> metaAnnotationTypes, @Nullable Map<String, Object> attributes) {
boolean isStereotype = annotationType.equals(COMPONENT_ANNOTATION_CLASSNAME) ||
metaAnnotationTypes.contains(COMPONENT_ANNOTATION_CLASSNAME) ||
annotationType.equals("javax.annotation.ManagedBean") ||
annotationType.equals("javax.inject.Named");
return (isStereotype && attributes != null && attributes.containsKey("value"));
}
/**
* Derive a default bean name from the given bean definition.
* <p>The default implementation delegates to {@link #buildDefaultBeanName(BeanDefinition)}.
* @param definition the bean definition to build a bean name for
* @param registry the registry that the given bean definition is being registered with
* @return the default bean name (never {@code null})
*/
protected String buildDefaultBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
return buildDefaultBeanName(definition);
}
/**
* Derive a default bean name from the given bean definition.
* <p>The default implementation simply builds a decapitalized version
* of the short class name: e.g. "mypackage.MyJdbcDao" -> "myJdbcDao".
* <p>Note that inner classes will thus have names of the form
* "outerClassName.InnerClassName", which because of the period in the
* name may be an issue if you are autowiring by name.
* @param definition the bean definition to build a bean name for
* @return the default bean name (never {@code null})
*/
protected String buildDefaultBeanName(BeanDefinition definition) {
String beanClassName = definition.getBeanClassName();
Assert.state(beanClassName != null, "No bean class name set");
String shortClassName = ClassUtils.getShortName(beanClassName);
//就是这里进行的转换
return Introspector.decapitalize(shortClassName);
}
}
1. 自定义beanName生成策略
需要创建一个类继承AnnotationBeanNameGenerator
重写方法buildDefaultBeanName(BeanDefinition definition)
public class MyBeanNameGenerator extends AnnotationBeanNameGenerator {
@Override
protected String buildDefaultBeanName(BeanDefinition definition) {
String beanClassName = definition.getBeanClassName();
Assert.state(beanClassName != null, "No bean class name set");
String shortClassName = ClassUtils.getShortName(beanClassName);
return Introspector.decapitalize(shortClassName);
}
}
-
注解方式
@ComponentScan(basePackages = "com.shy.spring", //主要是添加这个 nameGenerator = MyBeanNameGenerator.class) @Configuration public class AppConfig { }
-
xml配置文件方式
<context:component-scan base-package="com.shy.spring" name-generator="com.shy.spring.factoryconfig.MyBeanNameGenerator"/>
四. 环境准备
1.prepareBeanFactory(beanFactory)
- 设置了一个类加载器
- 设置了bean表达式解析器
- 添加了属性编辑器的支持
- 添加了一个后置处理器:ApplicationContextAwareProcessor,此后置处理器实现了BeanPostProcessor接口
- 设置了一些忽略自动装配的接口
- 设置了一些允许自动装配的接口,并且进行了赋值操作
- 在容器中还没有XX的bean的时候,帮我们注册beanName为XX的singleton bean
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
//设置类加载器:存在则直接设置/不存在则新建一个默认类加载器
beanFactory.setBeanClassLoader(getClassLoader());
//设置EL表达式解析器(Bean初始化完成后填充属性时会用到)
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//设置属性注册解析器PropertyEditor
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
//将当前的ApplicationContext对象交给ApplicationContextAwareProcessor类来处理,从而在Aware接口实现类中的注入applicationContext
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//设置忽略自动装配的接口
//完成之后会设置9个忽略接口,之前在创建DefaultListableBeanFactory的时候已经添加了三个忽略接口
//其实就是一些集合
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
//在普通工厂中未注册为可解析类型的BeanFactory接口。
// MessageSource registered (and found for autowiring) as a bean.
//essageSource注册(并为自动装配找到)为bean。
//注册可以解析的自动装配
//放到集合中
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
//将早期用于检测内部bean的后处理器注册为applicationlistener。
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
//如果当前BeanFactory包含loadTimeWeaver Bean,说明存在类加载期织入AspectJ,
// 则把当前BeanFactory交给类加载期BeanPostProcessor实现类LoadTimeWeaverAwareProcessor来处理,
// 从而实现类加载期织入AspectJ的目的。
// 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.
//接下来就是向单例池中注册一些bean实例
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());
}
//注册系统环境systemEnvironment组件Bean
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
五.invokeBeanFactoryPostProcessors
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) throws IllegalAccessException, InstantiationException {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
//如果有的话,先调用BeanDefinitionRegistryPostProcessors。
//被处理的Beans
Set<String> processedBeans = new HashSet<>();
//beanFactory是DefaultListableBeanFactory,是BeanDefinitionRegistry的实现类,所以肯定满足if
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//regularPostProcessors 用来存放BeanFactoryPostProcessor,
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
//registryProcessors 用来存放BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 循环传进来的beanFactoryPostProcessors,正常情况下,beanFactoryPostProcessors肯定没有数据
// 因为beanFactoryPostProcessors是获得手动添加的,而不是spring扫描的
// 只有手动调用annotationConfigApplicationContext.addBeanFactoryPostProcessor(XXX)才会有数据
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
// 判断postProcessor是不是BeanDefinitionRegistryPostProcessor,因为BeanDefinitionRegistryPostProcessor
// 扩展了BeanFactoryPostProcessor,所以这里先要判断是不是BeanDefinitionRegistryPostProcessor
// 是的话,直接执行postProcessBeanDefinitionRegistry方法,然后把对象装到registryProcessors里面去
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
} else {
//不是的话,就装到regularPostProcessors
regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
//一个临时变量,用来装载BeanDefinitionRegistryPostProcessor
//BeanDefinitionRegistry继承了PostProcessorBeanFactoryPostProcessor
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
//获得实现BeanDefinitionRegistryPostProcessor接口的类的BeanName:org.springframework.context.annotation.internalConfigurationAnnotationProcessor
// 并且装入数组postProcessorNames,我理解一般情况下,只会找到一个
// 这里又有一个坑,为什么我自己创建了一个实现BeanDefinitionRegistryPostProcessor接口的类,也打上了@Component注解
// 配置类也加上了@Component注解,但是这里却没有拿到
// 因为直到这一步,Spring还没有去扫描,扫描是在ConfigurationClassPostProcessor类中完成的,也就是下面的第一个
// invokeBeanDefinitionRegistryPostProcessors方法
//其实就是拿到ConfigurationClassPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//获得ConfigurationClassPostProcessor类,并且放到currentRegistryProcessors
//ConfigurationClassPostProcessor是很重要的一个类,它实现了BeanDefinitionRegistryPostProcessor接口
//BeanDefinitionRegistryPostProcessor接口又实现了BeanFactoryPostProcessor接口
//ConfigurationClassPostProcessor是极其重要的类
//里面执行了扫描Bean,Import,ImportResouce等各种操作
//用来处理配置类(有两种情况 一种是传统意义上的配置类,一种是普通的bean)的各种逻辑
//下面这行代码设计到了创建bean实例,
//就是返回一个ConfigurationClassPostProcessor对象
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//把name放到processedBeans,后续会根据这个集合来判断处理器是否已经被执行过了
processedBeans.add(ppName);
}
}
//处理排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//合并Processors,为什么要合并,因为registryProcessors是装载BeanDefinitionRegistryPostProcessor的
//一开始的时候,spring只会执行BeanDefinitionRegistryPostProcessor独有的方法
//而不会执行BeanDefinitionRegistryPostProcessor父类的方法,即BeanFactoryProcessor的方法
//所以这里需要把处理器放入一个集合中,后续统一执行父类的方法
registryProcessors.addAll(currentRegistryProcessors);
//可以理解为执行ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法
//Spring热插的体现,像ConfigurationClassPostProcessor就相当于一个组件,Spring很多事情就是交给组件去管理
//这个超级重要,走到这个方法去看看
//类扫描什么的都是在这里进行的
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//因为currentRegistryProcessors是一个临时变量,所以需要清除
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
// 再次根据BeanDefinitionRegistryPostProcessor获得BeanName,看这个BeanName是否已经被执行过了,有没有实现Ordered接口
// 如果没有被执行过,也实现了Ordered接口的话,把对象推送到currentRegistryProcessors,名称推送到processedBeans
// 如果没有实现Ordered接口的话,这里不把数据加到currentRegistryProcessors,processedBeans中,后续再做处理
// 这里才可以获得我们定义的实现了BeanDefinitionRegistryPostProcessor的Bean
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//执行我们自定义的BeanDefinitionRegistryPostProcessor
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
// 上面的代码是执行了实现了Ordered接口的BeanDefinitionRegistryPostProcessor,
// 下面的代码就是执行没有实现Ordered接口的BeanDefinitionRegistryPostProcessor
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
//registryProcessors集合装载BeanDefinitionRegistryPostProcessor
//上面的代码是执行子类独有的方法,这里需要再把父类的方法也执行一次
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
//regularPostProcessors装载BeanFactoryPostProcessor,执行BeanFactoryPostProcessor的方法
//但是regularPostProcessors一般情况下,是不会有数据的,只有在外面手动添加BeanFactoryPostProcessor,才会有数据
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
} else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
} else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}
1.invokeBeanDefinitionRegistryPostProcessors(…)
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
//接下来进入到这里
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
}
if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + registry);
}
this.registriesPostProcessed.add(registryId);
//重点来了
processConfigBeanDefinitions(registry);
}
2.org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions
/**
* Build and validate a configuration model based on the registry of
* 基于注册表构建和验证配置模型
* {@link Configuration} classes.
*/
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
//存放配置类的集合
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
String[] candidateNames = registry.getBeanDefinitionNames();
// 这个下面的循环就是为了找到注册的配置类的
// 并且添加到集合中
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
//尤其是这里就是为了选择配置类的
//里面方法很简单的
//最后还找了一个@Order注解
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// Return immediately if no @Configuration classes were found
if (configCandidates.isEmpty()) {
return;
}
// Sort by previously determined @Order value, if applicable
//这里会根据之前的Order注解进行排序
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
// Detect any custom bean name generation strategy supplied through the enclosing application context
SingletonBeanRegistry sbr = null;
//下面的判断是为了选择bean名称生成器的
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {
//他首先会从单例池中get一下名称生成器
//因为当前属于初始化阶段所以单例池中一定不会存在的
//现在单例池中仅仅有4个实例
//environment
//systemProperties
//systemEnvironment
//以上三个单例都是在环境准备阶段进行注册的
//接下来还有一个单例就是当前的org.springframework.context.annotation.internalConfigurationAnnotationProcessor
//ConfigurationClassPostProcessor
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
// Parse each @Configuration class
//解析每个@Configuration类
//这个里面有一个new ComponentScanAnnotationParser(...)
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
//候选人集合
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
//已经解析过的
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
//最重要的就是解析各种注解
// 解析配置类,在此处会解析配置类上的注解(ComponentScan扫描出的类,@Import注册的类,以及@Bean方法定义的类)
// 注意:这一步只会将加了@Configuration注解以及通过@ComponentScan注解扫描的类才会加入到BeanDefinitionMap中
// 通过其他注解(例如@Import、@Bean)的方式,在parse()方法这一步并不会将其解析为BeanDefinition放入到BeanDefinitionMap中,而是先解析成ConfigurationClass类
// 真正放入到map中是在下面的this.reader.loadBeanDefinitions()方法中实现的
parser.parse(candidates);
parser.validate();
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
candidates.clear();
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet<>();
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
for (String candidateName : newCandidateNames) {
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition bd = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
while (!candidates.isEmpty());
// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
// Clear cache in externally provided MetadataReaderFactory; this is a no-op
// for a shared cache since it'll be cleared by the ApplicationContext.
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
/**
* Post-processes a BeanFactory in search of Configuration class BeanDefinitions;
* any candidates are then enhanced by a {@link ConfigurationClassEnhancer}.
* Candidate status is determined by BeanDefinition attribute metadata.
* @see ConfigurationClassEnhancer
*/
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
for (String beanName : beanFactory.getBeanDefinitionNames()) {
BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef)) {
if (!(beanDef instanceof AbstractBeanDefinition)) {
throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" +
beanName + "' since it is not stored in an AbstractBeanDefinition subclass");
}
else if (logger.isWarnEnabled() && beanFactory.containsSingleton(beanName)) {
logger.warn("Cannot enhance @Configuration bean definition '" + beanName +
"' since its singleton instance has been created too early. The typical cause " +
"is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor " +
"return type: Consider declaring such methods as 'static'.");
}
configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
}
}
if (configBeanDefs.isEmpty()) {
// nothing to enhance -> return immediately
return;
}
ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
AbstractBeanDefinition beanDef = entry.getValue();
// If a @Configuration class gets proxied, always proxy the target class
beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
try {
// Set enhanced subclass of the user-specified bean class
Class<?> configClass = beanDef.resolveBeanClass(this.beanClassLoader);
if (configClass != null) {
Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
if (configClass != enhancedClass) {
if (logger.isDebugEnabled()) {
logger.debug(String.format("Replacing bean definition '%s' existing class '%s' with " +
"enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName()));
}
beanDef.setBeanClass(enhancedClass);
}
}
}
catch (Throwable ex) {
throw new IllegalStateException("Cannot load configuration class: " + beanDef.getBeanClassName(), ex);
}
}
}
3.ConfigurationClassPostProcessor#parse(configCandidates)
public void parse(Set<BeanDefinitionHolder> configCandidates) {
this.deferredImportSelectors = new LinkedList<>();
//解析配置类
for (BeanDefinitionHolder holder : configCandidates) {
//得到配置类的描述
BeanDefinition bd = holder.getBeanDefinition();
try {
//因为配置类一定是自己创建的AnnotatedBeanDefinition类型的
if (bd instanceof AnnotatedBeanDefinition) {
//接下俩一定会走这里
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
}
else {
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
}
}
processDeferredImportSelectors();
}
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
//走到这个方法
processConfigurationClass(new ConfigurationClass(metadata, beanName));
}
4.processConfigurationClass(ConfigurationClass configClass)
//他的参数主要是创建的ConfigurationClass对象
//它里面包含了配置类所含的注解,配置类的beanName,还有详情描述信息
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}
ConfigurationClass existingClass = this.configurationClasses.get(configClass);
//安全检查
if (existingClass != null) {
if (configClass.isImported()) {
if (existingClass.isImported()) {
existingClass.mergeImportedBy(configClass);
}
// Otherwise ignore new imported config class; existing non-imported class overrides it.
return;
}
else {
// Explicit bean definition found, probably replacing an import.
// Let's remove the old one and go with the new one.
this.configurationClasses.remove(configClass);
this.knownSuperclasses.values().removeIf(configClass::equals);
}
}
// Recursively process the configuration class and its superclass hierarchy.
//递归地处理配置类及其超类层次结构。
//里面方法还是很简单的 不用去看
// 处理配置类,由于配置类可能存在父类(若父类的全类名是以java开头的,则除外),所有需要将configClass变成sourceClass去解析,然后返回sourceClass的父类。
// 如果此时父类为空,则不会进行while循环去解析,如果父类不为空,则会循环的去解析父类
// SourceClass的意义:简单的包装类,目的是为了以统一的方式去处理带有注解的类,不管这些类是如何加载的
// 如果无法理解,可以把它当做一个黑盒,不会影响看spring源码的主流程
SourceClass sourceClass = asSourceClass(configClass);
do {
//这里是重点
sourceClass = doProcessConfigurationClass(configClass, sourceClass);
}
while (sourceClass != null);
this.configurationClasses.put(configClass, configClass);
}
5.doProcessConfigurationClass(configClass, sourceClass);
- 处理内部类,如果内部类也是一个配置类(判断一个类是否是一个配置类,通过ConfigurationClassUtils.checkConfigurationClassCandidate()可以判断)。
- (2) 处理属性资源文件,加了@PropertySource注解。
- (3) 首先解析出类上的@ComponentScan和@ComponentScans注解,然后根据配置的扫描包路径,利用ASM技术(ASM技术是一种操作字节码的技术,有兴趣的朋友可以去网上了解下)扫描出所有需要交给Spring管理的类,由于扫描出的类中可能也被加了@ComponentScan和@ComponentScans注解,因此需要进行递归解析,直到所有加了这两个注解的类被解析完成。
- (4) 处理@Import注解。通过@Import注解,有三种方式可以将一个Bean注册到Spring容器中。
- (5) 处理@ImportResource注解,解析配置文件。
- (6) 处理加了@Bean注解的方法。
- (7) 通过processInterfaces()处理接口的默认方法,从JDK8开始,接口中的方法可以有自己的默认实现,因此,如果这个接口中的方法也加了@Bean注解,也需要被解析。(很少用)
- (8) 解析父类,如果被解析的配置类继承了某个类,那么配置类的父类也会被进行解析doProcessConfigurationClass()(父类是JDK内置的类例外,即全类名以java开头的)。
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
throws IOException {
// Recursively process any member (nested) classes first
//首先递归地处理任何成员(嵌套的)类
processMemberClasses(configClass, sourceClass);
// Process any @PropertySource annotations
//处理任何@PropertySource注释
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.environment instanceof ConfigurableEnvironment) {
processPropertySource(propertySource);
}
else {
logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
// Process any @ComponentScan annotations
//处理所有@ComponentScan注释
//首先会解析出ComponentScans.class, ComponentScan.class
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
// The config class is annotated with @ComponentScan -> perform the scan immediately
// 配置类由@ComponentScan注释——>立即执行扫描
// 这里就是进行的扫描
// 接下俩将介绍一下这个方法
// 解析@ComponentScan和@ComponentScans配置的扫描的包所包含的类
// 比如 basePackages = com.shy.spring, 那么在这一步会扫描出这个包及子包下的class,然后将其解析成BeanDefinition
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// Check the set of scanned definitions for any further config classes and parse recursively if needed
//检查已扫描的定义集以获得更多的配置类,并在需要时进行递归解析
//通过上一步扫描包下的类,有可能扫描出来的bean中可能也添加了ComponentScan或者ComponentScans注解.
//所以这里需要循环遍历一次,进行递归(parse),继续解析,直到解析出的类上没有ComponentScan和ComponentScans
// (这时这一步解析出componentScans为空列表,不会进入到if语句,递归终止)
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// Process any @Import annotations
// 解析所有的@Import的标签
processImports(configClass, sourceClass, getImports(sourceClass), true);
// Process any @ImportResource annotations
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}
// Process individual @Bean methods
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// Process default methods on interfaces
processInterfaces(configClass, sourceClass);
// Process superclass, if any
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") &&
!this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
// Superclass found, return its annotation metadata and recurse
return sourceClass.getSuperClass();
}
}
// No superclass -> processing is complete
return null;
}
6.ComponentScanAnnotationParser#parse
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
//创建一个扫描器
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
//这个是拿到自定义的beanName生成器
Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
//判断是否是默认的
boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
//如果我们自定义了就会实例化 并进行设置
//如果我们没有进行定义的话 就会使用自己的发beanName生成器
//new AnnotationBeanNameGenerator(); 当创建对象的时候 这个类就进行了实例化
scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
BeanUtils.instantiateClass(generatorClass));
//判断是否需要创建作用域的代理模式
ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
scanner.setScopedProxyMode(scopedProxyMode);
}
else {
//默认的AnnotationScopeMetadataResolver(注解作用域元数据解析器)
Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
}
scanner.setResourcePattern(componentScan.getString("resourcePattern"));
for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addIncludeFilter(typeFilter);
}
}
for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addExcludeFilter(typeFilter);
}
}
//判断是否添加了懒加载标签
boolean lazyInit = componentScan.getBoolean("lazyInit");
if (lazyInit) {
scanner.getBeanDefinitionDefaults().setLazyInit(true);
}
//创建一个集合,用来存放所有的扫描包
Set<String> basePackages = new LinkedHashSet<>();
//从属性中的到字符串数组,就是我们配置的包扫描路径
String[] basePackagesArray = componentScan.getStringArray("basePackages");
//接下来的代码将会把各种各样的包扫描方式的路径整合到一起了
for (String pkg : basePackagesArray) {
String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
Collections.addAll(basePackages, tokenized);
}
for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
basePackages.add(ClassUtils.getPackageName(clazz));
}
if (basePackages.isEmpty()) {
basePackages.add(ClassUtils.getPackageName(declaringClass));
}
scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
@Override
protected boolean matchClassName(String className) {
return declaringClass.equals(className);
}
});
//接下来走到了这里,我们进去看看
return scanner.doScan(StringUtils.toStringArray(basePackages));
}
7.scanner.doScan(StringUtils.toStringArray(basePackages));
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
for (String basePackage : basePackages) {
//会通过扫描包把所有的标记了@Component注解的类封装成ScannedGenericBeanDefinition对象
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
// 判断没有个扫描类的类型
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
//生成bean的名称如果自己定义了的一定会走到自己的生成器
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
//一定会走到这里的,因为生成的ScannedGenericBeanDefinition必定是AbstractBeanDefinition
if (candidate instanceof AbstractBeanDefinition) {
//设置一些默认的属性
/*
public void applyDefaults(BeanDefinitionDefaults defaults) {
setLazyInit(defaults.isLazyInit());
setAutowireMode(defaults.getAutowireMode());
setDependencyCheck(defaults.getDependencyCheck());
setInitMethodName(defaults.getInitMethodName());
setEnforceInitMethod(false);
setDestroyMethodName(defaults.getDestroyMethodName());
setEnforceDestroyMethod(false);
}
*/
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
//解析公共的标签
//这个一定会进入的,但是之前已经介绍过了,在注册本身配置文件的时候
//这个方法是解析公共注解标签
//说一下一共解析了多少个注解
//@Lazy
//@Primary
//@DependsOn
//@Role
//@Description
if (candidate instanceof AnnotatedBeanDefinition) {
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
//检查给定候选bean的名称,确定是否需要注册对应的bean定义,或者是否与现有定义冲突。
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
//这个时候会直接注册到工厂的beanDefinitionMap中
//所以说什么时候注解标注了@Component注解被添加到Map中的就是现在
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
最后
以上就是文艺汉堡为你收集整理的spring5源码解读——XML二.BeanDefintion解析及注册(注解)的全部内容,希望文章能够帮你解决spring5源码解读——XML二.BeanDefintion解析及注册(注解)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复