Spring的使用对于我们java开发人员来说应该算是基本技能,在大学期间自学了Spring,当时也只是为了能完成功能的开发而学习,简单的使用,从xml配置的方式到注解的方式,刚开始都是@controller、@service、@component、@autowired这些注解。现在刚毕业来到公司上班发现其他同事都在用着其他的Spring特性,例如一些Aware、初始化注解@PostConstruct、AOP的一些技术。那这些特性用起来很方便也很简单,也有大部分的资料叫我们怎么用,但底层是如何实现的?源码中又藏着那些我们平时看不见却十分巧妙的地方?接下来我将Spring分为两个部分根据源码来讲解–IOC和AOP两部分。
首先迎来的是IOC这一部分,整个Spring容器的实例化bean过程其实做了很多事,也为我们提供了很多接口让我们在容器启动过程中实现自定义的干预。开始之前先说一点比较重要的东西,因为有些初学者可能是从xml配置开始学的,那么如果我从注解方式开始讲,就可能会直接劝退这部分读者,而且考虑到大部分读者对xml配置有所了解,所以我这里就直接从xml配置方式开始讲,在后面会将注解方式也完整的加入进来。同时读源码的过程是痛苦并快乐的,痛苦是一环扣一环,快乐是理解到了环环相扣的精髓,希望大家坚持,有不对或有疑问的地方也希望大家指出讨论,共同进步!那么接下来就开始吧。
我使用的版本是5.1.3.RELEASE,我们只要导入一个context包就可以了,因为他会依赖其他aop、bean、core等包。然后导入了一个Junit包来提供测试。
先运行起来看看结果,是没有问题的。基础的使用就不再这里说了,那么spring是如是做到这些的呢?为什么我们只需要getBean就能拿到实例呢?神秘的面纱还需要从这个ClassPathXmlApplicationContext开始。为了方便读者了解到是哪个类的哪些方法,所以在每个代码块中的第一行格式是:【类名 - 行号 - 代码块号】,这个代码块号是为了方便读者在看代码时找到函数之间的调用关系。接下里正式开始,先进入到ClassPathXmlApplicationContext的构造函数:
ClassPathXmlApplicationContext - 42 - N1
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
super(parent);
this.setConfigLocations(configLocations);
if (refresh) {
//N2 这里面用到了模板方法,这也是我们开发时候比较常见的以重设计模式,提高了扩展性
this.refresh();
}
}
AbstractApplicationContext - 258 - N2
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
//N3 创建了beanFactory对象/解析xml文件并封装成beanDefinition对象
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
/*
* 这个方法是spring中最重要的方法,没有之一
* 所以这个方法一定要理解要具体看
* 1、bean实例化过程
* 2、ioc
* 3、注解支持
* 4、BeanPostProcessor的执行
* 5、Aop的入口
*
* */
//N100
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
AbstractApplicationContext - 309 - N3
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//N4 在这里面会创建一个bean工厂
this.refreshBeanFactory();
return this.getBeanFactory();
}
AbstractRefreshableApplicationContext - 40 - N4
protected final void refreshBeanFactory() throws BeansException {
//先判断是否存在工厂,存在则清空bean实例和关闭工厂
if (this.hasBeanFactory()) {
this.destroyBeans();
this.closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = this.createBeanFactory();
beanFactory.setSerializationId(this.getId());
//N5 设置是否可以循环依赖和是否允许使用相同名称重新注册不同的bean实现
this.customizeBeanFactory(beanFactory);
//N6 从这里就开始解析xml,并把标签封装为beanDefinition
this.loadBeanDefinitions(beanFactory);
synchronized(this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
} catch (IOException var5) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
}
}
AbstractRefreshableApplicationContext - 102 -N5
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
//设置是否可以循环依赖和是否允许使用相同名称重新注册不同的bean实现
if (this.allowBeanDefinitionOverriding != null) {
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
//设置否允许使用相同名称重新注册不同的bean实现
if (this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
}
从这里开始就是对xml文档解析并且封装成BeanDefinition的过程。(后续beanDefinition我就直接用bd来表示,大家不要误解为数据库的BD了哈(●’◡’●))
AbstractXmlApplicationContext - 31 - N6
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
//这里是创建一个xml的解析器,将解析xml的任务交给这个解析器完成
//后面讲注解方法加载spring的时候会有个AnnotationBeanDefinitionReader,他们都是为了封装bd的作用
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.setEnvironment(this.getEnvironment());
//ApplicationContext是实现了ResourceLoader接口的
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
this.initBeanDefinitionReader(beanDefinitionReader);
//N7
this.loadBeanDefinitions(beanDefinitionReader);
}
AbstractXmlApplicationContext - 44 - N7
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = this.getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
//主要看这里,细心的读者可以发现在N1的ClassPathXmlApplicationContext有个setConfigLocations,
//这里的getConfigLocations刚好就可以拿到之前我们传进来的参数
String[] configLocations = this.getConfigLocations();
if (configLocations != null) {
//N8 拿到了xml的路径,现在我们就可以调用xml解析器的方法去解析整个xml文件
reader.loadBeanDefinitions(configLocations);
}
}
AbstractBeanDefinitionReader - 150 - N8
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
Assert.notNull(locations, "Location array must not be null");
int count = 0;
String[] var3 = locations;
int var4 = locations.length;
//可能存在多个文件,所以循环遍历xml文件路径locations
for(int var5 = 0; var5 < var4; ++var5) {
String location = var3[var5];
//N9 这里开始对每一个xml单独的解析并封装成db
count += this.loadBeanDefinitions(location);
}
return count;
}
AbstractBeanDefinitionReader - 108 - N9
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
//N10
return this.loadBeanDefinitions(location, (Set)null);
}
AbstractBeanDefinitionReader - 112 - N10
public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
//拿到资源加载器
ResourceLoader resourceLoader = this.getResourceLoader();
if (resourceLoader == null) {
throw new BeanDefinitionStoreException("Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
} else {
int count;
if (resourceLoader instanceof ResourcePatternResolver) {
try {
//这里通过资源加载器加载location路径的文件,当我们点进Resource类的时候就可以发现其实Resource
//类是继承了InputStreamSource,所以还是跟我们平时读取文件的方式差不多,都是stream流的方式
//这里设计到模糊匹配,十分复杂,感兴趣的读者自己可以尝试看看
Resource[] resources = ((ResourcePatternResolver)resourceLoader).getResources(location);
//N11 拿到了xml文件对应的Resource对象后继续往下走
count = this.loadBeanDefinitions(resources);
if (actualResources != null) {
Collections.addAll(actualResources, resources);
}
if (this.logger.isTraceEnabled()) {
this.logger.trace("Loaded " + count + " bean definitions from location pattern [" + location + "]");
}
return count;
} catch (IOException var6) {
throw new BeanDefinitionStoreException("Could not resolve bean definition resource pattern [" + location + "]", var6);
}
} else {
Resource resource = resourceLoader.getResource(location);
count = this.loadBeanDefinitions((Resource)resource);
if (actualResources != null) {
actualResources.add(resource);
}
if (this.logger.isTraceEnabled()) {
this.logger.trace("Loaded " + count + " bean definitions from location [" + location + "]");
}
return count;
}
}
}
AbstractBeanDefinitionReader - 94 - N11
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
Assert.notNull(resources, "Resource array must not be null");
int count = 0;
Resource[] var3 = resources;
int var4 = resources.length;
for(int var5 = 0; var5 < var4; ++var5) {
Resource resource = var3[var5];
//N12 因为可能存在多个xml文件的Resource,所以又会对Resource遍历
count += this.loadBeanDefinitions((Resource)resource);
}
return count;
}
XmlBeanDefinitionReader - 138 - N12
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
//N13 转化为了带编码的对Resource对象的封装
//这个带编码的EncodedResource其实里面就是用属性装着Resource和Encoding
return this.loadBeanDefinitions(new EncodedResource(resource));
}
XmlBeanDefinitionReader - 142 - N13
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (this.logger.isTraceEnabled()) {
this.logger.trace("Loading XML bean definitions from " + encodedResource);
}
Set<EncodedResource> currentResources = (Set)this.resourcesCurrentlyBeingLoaded.get();
if (currentResources == null) {
currentResources = new HashSet(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
}
if (!((Set)currentResources).add(encodedResource)) {
throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!");
} else {
int var5;
try {
//从EncodedResource中拿到Resource对象然后拿到InputStream对象
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
//将inputStream封装成InputSource对象
InputSource inputSource = new InputSource(inputStream);
//如果编码不为空则需要给InputSource设置编码
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
//N14
var5 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());
} finally {
inputStream.close();
}
} catch (IOException var15) {
throw new BeanDefinitionStoreException("IOException parsing XML document from " + encodedResource.getResource(), var15);
} finally {
((Set)currentResources).remove(encodedResource);
if (((Set)currentResources).isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
return var5;
}
}
XmlBeanDefinitionReader - 193 - N14
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
try {
//直接先把inputSource封装成Document对象
Document doc = this.doLoadDocument(inputSource, resource);
//N15 走到这里xml文件算是获取完毕了,现在就是对xml文件内的元素解析了
int count = this.registerBeanDefinitions(doc, resource);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Loaded " + count + " bean definitions from " + resource);
}
return count;
} catch (BeanDefinitionStoreException var5) {
throw var5;
} catch (SAXParseException var6) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(), "Line " + var6.getLineNumber() + " in XML document from " + resource + " is invalid", var6);
} catch (SAXException var7) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(), "XML document from " + resource + " is invalid", var7);
} catch (ParserConfigurationException var8) {
throw new BeanDefinitionStoreException(resource.getDescription(), "Parser configuration exception parsing XML from " + resource, var8);
} catch (IOException var9) {
throw new BeanDefinitionStoreException(resource.getDescription(), "IOException parsing XML document from " + resource, var9);
} catch (Throwable var10) {
throw new BeanDefinitionStoreException(resource.getDescription(), "Unexpected exception parsing XML document from " + resource, var10);
}
}
XmlBeanDefinitionReader - 250 - N15
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
//创建一个BeanDefinitionDocumentReader解析对象
BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader();
int countBefore = this.getRegistry().getBeanDefinitionCount();
//N16 前面我们把xml交给了xmlBeanDefinitionReader对象去解析,现在我们解析Document对象一样是将对
//象交给BeanDefinitionDocumentReader对象去完成解析任务
documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
return this.getRegistry().getBeanDefinitionCount() - countBefore;
}
DefaultBeanDefinitionDocumentReader - 47 - N16
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
//N17 这里将root节点传进去
this.doRegisterBeanDefinitions(doc.getDocumentElement());
}
DefaultBeanDefinitionDocumentReader - 62 - N17
protected void doRegisterBeanDefinitions(Element root) {
BeanDefinitionParserDelegate parent = this.delegate;
this.delegate = this.createDelegate(this.getReaderContext(), root, parent);
if (this.delegate.isDefaultNamespace(root)) {
String profileSpec = root.getAttribute("profile");
if (StringUtils.hasText(profileSpec)) {
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec, ",; ");
if (!this.getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + this.getReaderContext().getResource());
}
return;
}
}
}
//这里又用到了模板方法,preProcessXml和postProcessXml两个是模板方法
this.preProcessXml(root);
//N18 这里面就开始从root节点解析这个xml的标签了
this.parseBeanDefinitions(root, this.delegate);
this.postProcessXml(root);
this.delegate = parent;
}
上面所做的所有步骤都是为了完成一件事—读取xml配置文件,从我们传入的location路径,然后将这个xml文件用Stream流的方式读取到,转为document对象,到现在这一步拿到它的root对象准备开始遍历。而spring在实例化bean的时候操作的是beanDefinition对象,所以接下来也是在实例化前比较关键的一步—将默认标签和自定义标签分别解析成beanDefinition。这里说到默认标签主要就有四种:bean、import、alias、beans四种标签,这些标签中可能会包含有自定义属性和自定义标签。那么自定义标签也是有特征的,就拿下面这个图来说,它是带一个标签头的(context就是这个标签头)。首先从默认标签开始讲,因为bean是最常用也是最复杂的默认标签所以会以bean标签的解析来讲解(其他三种流程都是差不多的)。
DefaultBeanDefinitionDocumentReader - 91 - N18
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
//拿到root标签的子标签节点List
NodeList nl = root.getChildNodes();
//遍历子标签List
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)) {
//N19 如果是默认标签则进入这里
this.parseDefaultElement(ele, delegate);
} else {
//N44 如果是自定义标签则进入这里
delegate.parseCustomElement(ele);
}
}
}
} else {
delegate.parseCustomElement(root);
}
}
DefaultBeanDefinitionDocumentReader - 112 - N19
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, "import")) {
this.importBeanDefinitionResource(ele);
} else if (delegate.nodeNameEquals(ele, "alias")) {
this.processAliasRegistration(ele);
} else if (delegate.nodeNameEquals(ele, "bean")) {
//这里只看这一步,其他三种流程都是相似的
this.processBeanDefinition(ele, delegate);
} else if (delegate.nodeNameEquals(ele, "beans")) {
this.doRegisterBeanDefinitions(ele);
}
}
DefaultBeanDefinitionDocumentReader - 201 - N20
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
//N21 这一步是将<bean>标签解析成bd,然后将默认属性和子默认标签封装进bd,最后封装成beanDefinitionHolder,后面为了方便也是将beanDefinitionHolder简写成bdh
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
//N25 执行到这里,说明已经执行完了N21-24的默认标签包含的默认属性和默认标签的解析。
// 接下来就是默认标签包含的自定义属性和自定义标签。
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
//N28 注册这个Bean到map和list中
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());
} catch (BeanDefinitionStoreException var5) {
this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);
}
this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
BeanDefinitionParserDelegate - 228 - N21
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
//N22
return this.parseBeanDefinitionElement(ele, (BeanDefinition)null);
}
BeanDefinitionParserDelegate - 233 - N22
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
String id = ele.getAttribute("id");
String nameAttr = ele.getAttribute("name");
List<String> aliases = new ArrayList();
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, ",; ");
aliases.addAll(Arrays.asList(nameArr));
}
String beanName = id;
if (!StringUtils.hasText(id) && !aliases.isEmpty()) {
beanName = (String)aliases.remove(0);
if (this.logger.isTraceEnabled()) {
this.logger.trace("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases");
}
}
//检查是否有重复的BeanName
if (containingBean == null) {
this.checkNameUniqueness(beanName, aliases, ele);
}
//N23 这一步才是最重要的
AbstractBeanDefinition beanDefinition = this.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 (this.logger.isTraceEnabled()) {
this.logger.trace("Neither XML 'id' nor 'name' specified - using generated bean name [" + beanName + "]");
}
} catch (Exception var9) {
this.error(var9.getMessage(), ele);
return null;
}
}
String[] aliasesArray = StringUtils.toStringArray(aliases);
//这里将上面封装好的bd和beanName和别名AliasesArray三个封装成BeanDefinitionHolder返回
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
} else {
return null;
}
}
BeanDefinitionParserDelegate - 303 - N23
public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, @Nullable BeanDefinition containingBean) {
this.parseState.push(new BeanEntry(beanName));
String className = null;
//bean的类名
if (ele.hasAttribute("class")) {
className = ele.getAttribute("class").trim();
}
//如果有父类,则将父类传入到bd的构造函数中,它会赋值到bd的parent属性中,如果没有则传null
String parent = null;
if (ele.hasAttribute("parent")) {
parent = ele.getAttribute("parent");
}
try {
//实际上返回的是GenericBeanDefinition,他是AbstractBeanDefinition的子类
AbstractBeanDefinition bd = this.createBeanDefinition(className, parent);
//下面的其实就是对各种属性和标签的判断、设值、判断、设值的过程,这些属性和标签的作用应该大家都懂得吧,毕竟来看源码的读者应该都是有实际经验的,后续有必要我也会专门写一篇关于xml配置的文章(觉得有需要的可以留言(*^_^*)),这里就暂时不讲解每个属性和标签的用法和作用了。
//N24 这一步是解析<bean>标签的属性赋值到bd中
this.parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, "description"));
//解析bean中的meta标签
this.parseMetaElements(ele, bd);
//解析bean中的lookup-method标签
this.parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
//解析bean中的replaced-method标签
this.parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
//解析bean中的constructor-arg标签
this.parseConstructorArgElements(ele, bd);
//解析bean中的property标签
this.parsePropertyElements(ele, bd);
this.parseQualifierElements(ele, bd);
bd.setResource(this.readerContext.getResource());
bd.setSource(this.extractSource(ele));
AbstractBeanDefinition var7 = bd;
return var7;
} catch (ClassNotFoundException var13) {
this.error("Bean class [" + className + "] not found", ele, var13);
} catch (NoClassDefFoundError var14) {
this.error("Class that bean class [" + className + "] depends on not found", ele, var14);
} catch (Throwable var15) {
this.error("Unexpected failure during bean definition parsing", ele, var15);
} finally {
this.parseState.pop();
}
return null;
}
BeanDefinitionParserDelegate - 342 - N24
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName, @Nullable BeanDefinition containingBean, AbstractBeanDefinition bd) {
//有些属性后面章节会讲到如何实现的,一步步来,例如init-method、destroy-method这些属性。
if (ele.hasAttribute("singleton")) {
this.error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele);
} else if (ele.hasAttribute("scope")) {
bd.setScope(ele.getAttribute("scope"));
} else if (containingBean != null) {
bd.setScope(containingBean.getScope());
}
//设置是否是抽象的,如果是抽象的则后续不会被实例化
if (ele.hasAttribute("abstract")) {
bd.setAbstract("true".equals(ele.getAttribute("abstract")));
}
//设置懒加载lazy-init
String lazyInit = ele.getAttribute("lazy-init");
if ("default".equals(lazyInit)) {
lazyInit = this.defaults.getLazyInit();
}
bd.setLazyInit("true".equals(lazyInit));
//Autowire属性
String autowire = ele.getAttribute("autowire");
bd.setAutowireMode(this.getAutowireMode(autowire));
String autowireCandidate;
//depends-on属性
if (ele.hasAttribute("depends-on")) {
autowireCandidate = ele.getAttribute("depends-on");
bd.setDependsOn(StringUtils.tokenizeToStringArray(autowireCandidate, ",; "));
}
//autowire-candidate属性
autowireCandidate = ele.getAttribute("autowire-candidate");
String destroyMethodName;
if (!"".equals(autowireCandidate) && !"default".equals(autowireCandidate)) {
bd.setAutowireCandidate("true".equals(autowireCandidate));
} else {
destroyMethodName = this.defaults.getAutowireCandidates();
if (destroyMethodName != null) {
String[] patterns = StringUtils.commaDelimitedListToStringArray(destroyMethodName);
bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));
}
}
if (ele.hasAttribute("primary")) {
bd.setPrimary("true".equals(ele.getAttribute("primary")));
}
//init-method 这个属性指定的方法在bean实例化后spring会帮我们调用此方法来达到初始化的作用(后面会详细讲到调用过程是如何实现的)
if (ele.hasAttribute("init-method")) {
destroyMethodName = ele.getAttribute("init-method");
bd.setInitMethodName(destroyMethodName);
} else if (this.defaults.getInitMethod() != null) {
bd.setInitMethodName(this.defaults.getInitMethod());
bd.setEnforceInitMethod(false);
}
//destroy-method 这个属性会在bean销毁前调用到(后面会详细讲到调用过程是如何实现的)
if (ele.hasAttribute("destroy-method")) {
destroyMethodName = ele.getAttribute("destroy-method");
bd.setDestroyMethodName(destroyMethodName);
} else if (this.defaults.getDestroyMethod() != null) {
bd.setDestroyMethodName(this.defaults.getDestroyMethod());
bd.setEnforceDestroyMethod(false);
}
//factory-method和factory-bean这两个也很重要,是实现@Bean的基础(后面会详细讲到调用过程是如何实现的)
if (ele.hasAttribute("factory-method")) {
bd.setFactoryMethodName(ele.getAttribute("factory-method"));
}
if (ele.hasAttribute("factory-bean")) {
bd.setFactoryBeanName(ele.getAttribute("factory-bean"));
}
return bd;
}
BeanDefinitionParserDelegate - 1041 - N25
public BeanDefinitionHolder decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder definitionHolder) {
//N26 将ele和bdh传入处理,ele当前的标签node对象,bdh就是已经解析完了默认属性和子默认标签的对象
return this.decorateBeanDefinitionIfRequired(ele, definitionHolder, (BeanDefinition)null);
}
BeanDefinitionParserDelegate - 1045 - N26
public BeanDefinitionHolder decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder definitionHolder, @Nullable BeanDefinition containingBd) {
BeanDefinitionHolder finalDefinition = definitionHolder;
NamedNodeMap attributes = ele.getAttributes();
for(int i = 0; i < attributes.getLength(); ++i) {
Node node = attributes.item(i);
//N27 解析默认标签中的自定义属性
finalDefinition = this.decorateIfRequired(node, finalDefinition, containingBd);
}
NodeList children = ele.getChildNodes();
for(int i = 0; i < children.getLength(); ++i) {
Node node = children.item(i);
if (node.getNodeType() == 1) {
//N27 解析默认标签中的自定义标签
finalDefinition = this.decorateIfRequired(node, finalDefinition, containingBd);
}
}
return finalDefinition;
}
BeanDefinitionParserDelegate - 1066 - N27
public BeanDefinitionHolder decorateIfRequired(Node node, BeanDefinitionHolder originalDef, @Nullable BeanDefinition containingBd) {
//根据node获取到命名空间uri例如前面N18上的图中
//http://www.springframework.org/schema/p 就是 p:username="purple"属性的uri
String namespaceUri = this.getNamespaceURI(node);
if (namespaceUri != null && !this.isDefaultNamespace(namespaceUri)) {
//N30 通过Uri获得对应的处理器,在处理器中有三个Map(parsers、decorators、attributeDecorators)
//其中后两者用来装饰默认标签的beanDefinition(现在使用),前者用来解析自定义标签的(后面使用)
//解释下,自定义标签或属性分两部分,中间由:分割,左边是标签头,右边是localName
//namespaceUri确定的是处理类对象,每个处理类对象中有很多个解析对象,而localName确定解析对象
//这个获取处理器是通过SPI服务发现的思想实现的。(后面章节也会专门写一篇文章来说明)
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler != null) {
//N32调用处理器的装饰方法decorate来装饰beanDefinition,最后返回装饰后的beanDefinition对象
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/")) {
this.error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", node);
} else if (this.logger.isDebugEnabled()) {
this.logger.debug("No Spring NamespaceHandler found for XML schema namespace [" + namespaceUri + "]");
}
}
return originalDef;
}
BeanDefinitionReaderUtils - 70 - N28
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
String beanName = definitionHolder.getBeanName();
//N29 注册beanDefinition到map和list中
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
String[] var4 = aliases;
int var5 = aliases.length;
for(int var6 = 0; var6 < var5; ++var6) {
String alias = var4[var6];
//此处注册了beanName和别名的映射关系
registry.registerAlias(beanName, alias);
}
}
}
DefaultListableBeanFactory - 676 - N29
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 {
((AbstractBeanDefinition)beanDefinition).validate();
} catch (BeanDefinitionValidationException var9) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var9);
}
}
BeanDefinition existingDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
if (!this.isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
if (existingDefinition.getRole() < beanDefinition.getRole()) {
if (this.logger.isInfoEnabled()) {
this.logger.info("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
}
} else if (!beanDefinition.equals(existingDefinition)) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
}
} else if (this.logger.isTraceEnabled()) {
this.logger.trace("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
}
this.beanDefinitionMap.put(beanName, beanDefinition);
} else {
if (this.hasBeanCreationStarted()) {
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 {
//这个map存的是beanName-beanDefinition的应映射关系
this.beanDefinitionMap.put(beanName, beanDefinition);
//这个list存的是beanName
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || this.containsSingleton(beanName)) {
this.resetBeanDefinition(beanName);
}
}
DefaultNamespaceHandlerResolver - 47 - N30
public NamespaceHandler resolve(String namespaceUri) {
//这个map存着所有的handle处理对象,key就是namespaceUri,而value可能是处理类对象或者处理类名
Map<String, Object> handlerMappings = this.getHandlerMappings();
//这里拿到了自定义标签所对应的处理类名
Object handlerOrClassName = handlerMappings.get(namespaceUri);
if (handlerOrClassName == null) {
return null;
} else if (handlerOrClassName instanceof NamespaceHandler) {
//如果是处理类对象则直接返回
return (NamespaceHandler)handlerOrClassName;
} else {
//如果是类名则通过反射创建实例对象并调用init初始化方法来初始化对象后存入缓存,然后返回
String className = (String)handlerOrClassName;
try {
Class<?> handlerClass = ClassUtils.forName(className, this.classLoader);
if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) {
throw new FatalBeanException("Class [" + className + "] for namespace [" + namespaceUri + "] does not implement the [" + NamespaceHandler.class.getName() + "] interface");
} else {
//这里反射创建handle处理对象,并调用handle的init()方法
NamespaceHandler namespaceHandler = (NamespaceHandler)BeanUtils.instantiateClass(handlerClass);
//N31 在init方法内会将localName和对应的解析类对象映射关系放到parsers这个map中
namespaceHandler.init();
//将这个handle放入map中,然后返回处理器
handlerMappings.put(namespaceUri, namespaceHandler);
return namespaceHandler;
}
} catch (ClassNotFoundException var7) {
throw new FatalBeanException("Could not find NamespaceHandler class [" + className + "] for namespace [" + namespaceUri + "]", var7);
} catch (LinkageError var8) {
throw new FatalBeanException("Unresolvable class definition for NamespaceHandler class [" + className + "] for namespace [" + namespaceUri + "]", var8);
}
}
}
AopNamespaceHandler - 14 - N31
//这里以AOP的处理类为例,init时初始化了aspectj-autoproxy、scoped-proxy、spring-configured三种解析对象
//的映射关系到parsers这个map中。
public void init() {
this.registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
this.registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
this.registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
this.registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
}
NamespaceHandlerSupport - 43 - N32
public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) {
//N33 这一步就是去N27中提到的后两个map中拿到装饰器对象
BeanDefinitionDecorator decorator = this.findDecoratorForNode(node, parserContext);
//得到了装饰器然后调用装饰对象的decorate装饰方法给beanDefinition装饰,这里面用到了装饰者设计模式
return decorator != null ? decorator.decorate(node, definition, parserContext) : null;
}
NamespaceHandlerSupport - 49 - N33
private BeanDefinitionDecorator findDecoratorForNode(Node node, ParserContext parserContext) {
BeanDefinitionDecorator decorator = null;
//localName就是自定义标签或属性后的:后面部分
String localName = parserContext.getDelegate().getLocalName(node);
if (node instanceof Element) {
decorator = (BeanDefinitionDecorator)this.decorators.get(localName);
} else if (node instanceof Attr) {
decorator = (BeanDefinitionDecorator)this.attributeDecorators.get(localName);
} else {
parserContext.getReaderContext().fatal("Cannot decorate based on Nodes of type [" + node.getClass().getName() + "]", node);
}
if (decorator == null) {
parserContext.getReaderContext().fatal("Cannot locate BeanDefinitionDecorator for " + (node instanceof Element ? "element" : "attribute") + " [" + localName + "]", node);
}
return decorator;
}
至此默认标签的属性及其子标签就解析完成并且注册到BeanDefinitionRegistry中。那么接下来回到N18,开始对自定义标签进行解析。(N34-N43是预留位置,后面可能会有补充,接下来从N44开始)
BeanDefinitionParserDelegate - 1021 - N44
public BeanDefinition parseCustomElement(Element ele) {
//N45 下面就开始解析自定义标签,其实跟解析默认标签中的自定义属性和标签思路是一样的
return this.parseCustomElement(ele, (BeanDefinition)null);
}
BeanDefinitionParserDelegate - 1026 - N45
public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
//根据node获取到命名空间uri例如前面N18上的图中
//context的uri是:http://www.springframework.org/schema/context
String namespaceUri = this.getNamespaceURI(ele);
if (namespaceUri == null) {
return null;
} else {
//N30 这个resolve方法跟解析默认标签中的自定义属性和标签那里是一样的(N27中),返回一个处理器
//这个处理器的init方法在resolve中被调用,初始化了所有解析对象到map中(parsers这个map)
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler == null) {
this.error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
return null;
} else {
//N46 这一步就是调用相对应的处理器的处理方法parse()
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
}
}
NamespaceHandlerSupport - 26 - N46
public BeanDefinition parse(Element element, ParserContext parserContext) {
//N47 这个跟N32中的findDecoratorForNode()方法很类似,只是这里不是获取装饰器而是获取解析对象
BeanDefinitionParser parser = this.findParserForElement(element, parserContext);
//N48 调用解析对象的parse()方法,这里我拿我们每个人都用过的
//<context:component-scan base-package="com.kaka"></context:component-scan>
//这个自定义标签的解析对象ComponentScanBeanDefinitionParser来讲解下它的大致流程,其他解析类的流程是相通的。
return parser != null ? parser.parse(element, parserContext) : null;
}
NamespaceHandlerSupport - 32 - N47
//这个方法和N33很类似,N33是获取装饰器这里是获取解析对象,他们是存储在NamespaceHandlerSupport中的三个map中
private BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext) {
//<context:component-scan>标签中localName就是:后面的component-scan
String localName = parserContext.getDelegate().getLocalName(element);
//通过localName拿到对应的解析对象,这里拿到的是ComponentScanBeanDefinitionParser这个类的实例
BeanDefinitionParser parser = (BeanDefinitionParser)this.parsers.get(localName);
if (parser == null) {
parserContext.getReaderContext().fatal("Cannot locate BeanDefinitionParser for element [" + localName + "]", element);
}
return parser;
}
ComponentScanBeanDefinitionParser - 50 - N48
public BeanDefinition parse(Element element, ParserContext parserContext) {
//获取到标签中base-package属性的值
String basePackage = element.getAttribute("base-package");
basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);
//将basePackage字符串以,切割开来得到basePackages数组,这个数组包含的包就是我们接下来要扫描的包,那扫描包里的什么呢??
String[] basePackages = StringUtils.tokenizeToStringArray(basePackage, ",; \t\n");
//N49 创建扫描器,在创建扫描器的时候就会创建过滤器来规定过滤哪些注解,忽略哪些注解
ClassPathBeanDefinitionScanner scanner = this.configureScanner(parserContext, element);
//N53 扫描并把扫描的类封装成beanDefinition对象 核心方法
Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
//N64 这里面会注册几个比较重要的BeanPostProcessor //AutowiredAnnotationBeanPostProcessor,ConfigurationClassPostProcessor,CommonAnnotationBeanPostProcessor
this.registerComponents(parserContext.getReaderContext(), beanDefinitions, element);
return null;
}
ComponentScanBeanDefinitionParser - 60 - N49
protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) {
//使用默认的过滤器
boolean useDefaultFilters = true;
if (element.hasAttribute("use-default-filters")) {
useDefaultFilters = Boolean.valueOf(element.getAttribute("use-default-filters"));
}
//N50 创建注解扫描器 这里使用默认的过滤器useDefaultFilters=true
ClassPathBeanDefinitionScanner scanner = this.createScanner(parserContext.getReaderContext(), useDefaultFilters);
scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults());
scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns());
if (element.hasAttribute("resource-pattern")) {
scanner.setResourcePattern(element.getAttribute("resource-pattern"));
}
try {
this.parseBeanNameGenerator(element, scanner);
} catch (Exception var7) {
parserContext.getReaderContext().error(var7.getMessage(), parserContext.extractSource(element), var7.getCause());
}
try {
this.parseScope(element, scanner);
} catch (Exception var6) {
parserContext.getReaderContext().error(var6.getMessage(), parserContext.extractSource(element), var6.getCause());
}
this.parseTypeFilters(element, scanner, parserContext);
return scanner;
}
ComponentScanBeanDefinitionParser - 89 - N50
protected ClassPathBeanDefinitionScanner createScanner(XmlReaderContext readerContext, boolean useDefaultFilters) {
//N51 进入创建扫描器的构造函数
return new ClassPathBeanDefinitionScanner(readerContext.getRegistry(), useDefaultFilters, readerContext.getEnvironment(), readerContext.getResourceLoader());
}
ClassPathBeanDefinitionScanner - 48 - N51
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment, @Nullable ResourceLoader resourceLoader) {
this.beanDefinitionDefaults = new BeanDefinitionDefaults();
this.beanNameGenerator = new AnnotationBeanNameGenerator();
this.scopeMetadataResolver = new AnnotationScopeMetadataResolver();
this.includeAnnotationConfig = true;
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
this.registry = registry;
if (useDefaultFilters) {
//N52 这里注册默认过滤器到扫描器中
this.registerDefaultFilters();
}
this.setEnvironment(environment);
this.setResourceLoader(resourceLoader);
}
ClassPathScanningCandidateComponentProvider - 111 - N52
protected void registerDefaultFilters() {
//在这个类中我们会发现只添加了component到过滤器中,但是我们在使用的时候,spring会为我们扫描除了@component注解外的如@controller@service等 //注解,这个原因是因为这些注解上面都继承自@component注解,这些注解在声明时都添加了@component,所以我们能扫描到@component注解及其子注解
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
this.includeFilters.add(new AnnotationTypeFilter(ClassUtils.forName("javax.annotation.ManagedBean", cl), false));
this.logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
} catch (ClassNotFoundException var4) {
}
try {
this.includeFilters.add(new AnnotationTypeFilter(ClassUtils.forName("javax.inject.Named", cl), false));
this.logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
} catch (ClassNotFoundException var3) {
}
}
ClassPathBeanDefinitionScanner - 105 - N53
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet();
String[] var3 = basePackages;
int var4 = basePackages.length;
for(int var5 = 0; var5 < var4; ++var5) {
String basePackage = var3[var5];
//N54 这里是获取到所有符合条件的类(也就是包含过滤器中的注解的类)并封装成beanDefinition,只是这些bd还未赋值到各个属性中
Set<BeanDefinition> candidates = this.findCandidateComponents(basePackage);
Iterator var8 = candidates.iterator();
//遍历符合条件的beanDefinition集合Set,然后从bd中拿出metadata分别赋值到bd中各个属性
while(var8.hasNext()) {
BeanDefinition candidate = (BeanDefinition)var8.next();
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
//设置scope属性
candidate.setScope(scopeMetadata.getScopeName());
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
this.postProcessBeanDefinition((AbstractBeanDefinition)candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
//N61 支持了@Lazy @DependOn注解
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition)candidate);
}
if (this.checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
//N63 将beanDefinition注册到map和list容器中
this.registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
ClassPathScanningCandidateComponentProvider - 178 - N54
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
//N55 进入到scanCandidateComponents
return this.componentsIndex != null && this.indexSupportsIncludeFilters() ? this.addCandidateComponentsFromIndex(this.componentsIndex, basePackage) : this.scanCandidateComponents(basePackage);
}
ClassPathScanningCandidateComponentProvider - 267 - N55
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
LinkedHashSet candidates = new LinkedHashSet();
try {
String packageSearchPath = "classpath*:" + this.resolveBasePackage(basePackage) + '/' + this.resourcePattern;
//N56 递归寻找文件
Resource[] resources = this.getResourcePatternResolver().getResources(packageSearchPath);
boolean traceEnabled = this.logger.isTraceEnabled();
boolean debugEnabled = this.logger.isDebugEnabled();
Resource[] var7 = resources;
int var8 = resources.length;
//这里找到了base-package属性(N46中的base-package="com.kaka")路径中的所有class文件并遍历
for(int var9 = 0; var9 < var8; ++var9) {
Resource resource = var7[var9];
if (traceEnabled) {
this.logger.trace("Scanning " + resource);
}
//判断文件可读性
if (resource.isReadable()) {
try {
//N57 包装了类的基本信息的对象
MetadataReader metadataReader = this.getMetadataReaderFactory().getMetadataReader(resource);
//N60 通过类的基本信息对象可以判断类上是否有包含includeFilters注解
if (this.isCandidateComponent(metadataReader)) {
//进入这里则说明类上含有includeFilters中的注解,则需要spring实例化,所以要封装成BeanDefinition
//这里封装成ScannedGenericBeanDefinition类,将metadataReader中的annotationMetadata属性赋值给
//ScannedGenericBeanDefinition类中的metadata属性,这个属性就是记录了类信息的对象,
//此时还未赋值给bd中各属性,只是在bd中用ScannedGenericBeanDefinition类对象存储
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setResource(resource);
sbd.setSource(resource);
if (this.isCandidateComponent((AnnotatedBeanDefinition)sbd)) {
if (debugEnabled) {
this.logger.debug("Identified candidate component class: " + resource);
}
candidates.add(sbd);
} else if (debugEnabled) {
this.logger.debug("Ignored because not a concrete top-level class: " + resource);
}
} else if (traceEnabled) {
this.logger.trace("Ignored because not matching any filter: " + resource);
}
} catch (Throwable var13) {
throw new BeanDefinitionStoreException("Failed to read candidate component class: " + resource, var13);
}
} else if (traceEnabled) {
this.logger.trace("Ignored because not readable: " + resource);
}
}
return candidates;
} catch (IOException var14) {
throw new BeanDefinitionStoreException("I/O failure during classpath scanning", var14);
}
}
PathMatchingResourcePatternResolver - 88 - N56
public Resource[] getResources(String locationPattern) throws IOException {
//这个类主要就是找到路径下的所有.class尾缀文件,就是一个匹配过程,这里不深究
Assert.notNull(locationPattern, "Location pattern must not be null");
if (locationPattern.startsWith("classpath*:")) {
return this.getPathMatcher().isPattern(locationPattern.substring("classpath*:".length())) ? this.findPathMatchingResources(locationPattern) : this.findAllClassPathResources(locationPattern.substring("classpath*:".length()));
} else {
int prefixEnd = locationPattern.startsWith("war:") ? locationPattern.indexOf("*/") + 1 : locationPattern.indexOf(58) + 1;
return this.getPathMatcher().isPattern(locationPattern.substring(prefixEnd)) ? this.findPathMatchingResources(locationPattern) : new Resource[]{this.getResourceLoader().getResource(locationPattern)};
}
}
CachingMetadataReaderFactory - 61 - N57
public MetadataReader getMetadataReader(Resource resource) throws IOException {
if (this.metadataReaderCache instanceof ConcurrentMap) {
MetadataReader metadataReader = (MetadataReader)this.metadataReaderCache.get(resource);
if (metadataReader == null) {
metadataReader = super.getMetadataReader(resource);
this.metadataReaderCache.put(resource, metadataReader);
}
return metadataReader;
} else if (this.metadataReaderCache != null) {
synchronized(this.metadataReaderCache) {
MetadataReader metadataReader = (MetadataReader)this.metadataReaderCache.get(resource);
if (metadataReader == null) {
metadataReader = super.getMetadataReader(resource);
this.metadataReaderCache.put(resource, metadataReader);
}
return metadataReader;
}
} else {
//N58 通过父类方法包装class文件信息为MetadataReader对象
return super.getMetadataReader(resource);
}
}
SimpleMetadataReaderFactory - 55 - N58
public MetadataReader getMetadataReader(Resource resource) throws IOException {
//N59 SimpleMetadataReader是MetadataReader的子类
return new SimpleMetadataReader(resource, this.resourceLoader.getClassLoader());
}
SimpleMetadataReader - 22 - N59
SimpleMetadataReader(Resource resource, @Nullable ClassLoader classLoader) throws IOException {
//先获取文件流,Resource是InputStreamSource的子类,调用getInputStream()就可以获得文件流
BufferedInputStream is = new BufferedInputStream(resource.getInputStream());
ClassReader classReader;
try {
classReader = new ClassReader(is);
} catch (IllegalArgumentException var9) {
throw new NestedIOException("ASM ClassReader failed to parse class file - probably due to a new Java class file version that isn't supported yet: " + resource, var9);
} finally {
is.close();
}
AnnotationMetadataReadingVisitor visitor = new AnnotationMetadataReadingVisitor(classLoader);
//AnnotationMetadataReadingVisitor是ClassMetadata和AnnotationMetadata的子类,这个visitor对象就是存储了文件类信息的对象
classReader.accept(visitor, 2);
this.annotationMetadata = visitor;
this.classMetadata = visitor;
this.resource = resource;
}
ClassPathScanningCandidateComponentProvider - 321 - N60
//在这个类会获取到excludeFilters和includeFilters两个过滤器来匹配这个类信息中的注解信息,
//如果类信息中注解信息没有excludeFilters中的注解且有includeFilters中的注解,则视为匹配成功
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
Iterator var2 = this.excludeFilters.iterator();
TypeFilter tf;
do {
if (!var2.hasNext()) {
var2 = this.includeFilters.iterator();
do {
if (!var2.hasNext()) {
//走到这里就是两个过滤器都没有,则表示匹配失败
return false;
}
tf = (TypeFilter)var2.next();
} while(!tf.match(metadataReader, this.getMetadataReaderFactory()));
//走到这里就是没有excludeFilters中的注解且有includeFilters中的注解,则表示匹配成功
return this.isConditionMatch(metadataReader);
}
tf = (TypeFilter)var2.next();
} while(!tf.match(metadataReader, this.getMetadataReaderFactory()));
//走到这里说明存在excludeFilters中的注解,所以匹配失败
return false;
}
AnnotationConfigUtils - 125 - N61
public static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) {
//N62
processCommonDefinitionAnnotations(abd, abd.getMetadata());
}
AnnotationConfigUtils - 129 - N62
static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
//对@Lazy注解的支持
if (lazy != null) {
abd.setLazyInit(lazy.getBoolean("value"));
} else if (abd.getMetadata() != metadata) {
lazy = attributesFor(abd.getMetadata(), (Class)Lazy.class);
if (lazy != null) {
abd.setLazyInit(lazy.getBoolean("value"));
}
}
//@Primary注解的支持
if (metadata.isAnnotated(Primary.class.getName())) {
abd.setPrimary(true);
}
//对@DependsOn注解的支持
AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
if (dependsOn != null) {
abd.setDependsOn(dependsOn.getStringArray("value"));
}
AnnotationAttributes role = attributesFor(metadata, Role.class);
if (role != null) {
abd.setRole(role.getNumber("value").intValue());
}
AnnotationAttributes description = attributesFor(metadata, Description.class);
if (description != null) {
abd.setDescription(description.getString("value"));
}
}
ClassPathBeanDefinitionScanner - 149 - N63
protected void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) {
//N28 这里注册和默认标签注册都是一样的,都是加入到map和list两个容器中
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
}
ComponentScanBeanDefinitionParser - 93 - N64
protected void registerComponents(XmlReaderContext readerContext, Set<BeanDefinitionHolder> beanDefinitions, Element element) {
Object source = readerContext.extractSource(element);
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), source);
Iterator var6 = beanDefinitions.iterator();
while(var6.hasNext()) {
BeanDefinitionHolder beanDefHolder = (BeanDefinitionHolder)var6.next();
compositeDef.addNestedComponent(new BeanComponentDefinition(beanDefHolder));
}
boolean annotationConfig = true;
if (element.hasAttribute("annotation-config")) {
annotationConfig = Boolean.valueOf(element.getAttribute("annotation-config"));
}
if (annotationConfig) {
//N65 这里面会注册几个比较重要的BeanPostProcessor,请务必记住这个点,后面会提到
Set<BeanDefinitionHolder> processorDefinitions = AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source);
Iterator var8 = processorDefinitions.iterator();
while(var8.hasNext()) {
BeanDefinitionHolder processorDefinition = (BeanDefinitionHolder)var8.next();
compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition));
}
}
readerContext.fireComponentRegistered(compositeDef);
}
AnnotationConfigUtils - 50 - N65
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
//这里注册ConfigurationClassPostProcessor,这个类作用很大,完成了@Bean的部分工作,还完成了注解方式启动spring的工作,后续会详细讲解这个类。
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
//这里注册AutowiredAnnotationBeanPostProcessor
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));
}
//这里注册CommonAnnotationBeanPostProcessor
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}