spring很是重要,所以就是干!
阅读spring源码的时候这三个模块尤其中要,因为是初学,所以
首先重点关注这三个模块
接下来就是开始搭建阅读spring源码的环境在idea 中用maven直接在github拉取
https://github.com/spring-projects/spring-framework
然后在idea terminal预编译直接下面的命令
./gradlew :spring-oxm:compileTestJava
出现就有了阅读环境
1.org.springframework.core.io.Resource
为 Spring 框架所有资源的抽象和访问接口
要得到xml里面的bean信息首先要对配置文件进行分装,也就是得到资源文件。
接下来就是资源文件的读取。交给了一个类XmlBeanDefinitionReader这个类才是对资源文件的加载。
加载需要调用XmlBeanDefinitionReader类中的loadBeanDefinitions方法。
BeanFactory xmlBeanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
加载的时候需要判断解析,这个文件的内容分时,重要的是bean的解析,但是要有承载bean属性信息的东西,这个就是BeanDefinition。
期间还要涉及到xml文件的验证......(建议初学者先熟悉流程之后在慢慢看)
Document doc = this.doLoadDocument(inputSource, resource);//得到配置文件的doc属性(建议初学者先熟悉流程之后在慢慢看)
return this.registerBeanDefinitions(doc, resource);//根据获取的 Document 实例,注册 Bean 信息
注册就是通过BeanDefinitionRegistry接口将bean注册到容器中beanFactory,在spring环境下所有用到的所有bean都需要在spring容器中。
重点分析:
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
//创建 BeanDefinitionDocumentReader 对象
1BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader();
//得到已注册的 BeanDefinition 数量
2int countBefore = this.getRegistry().getBeanDefinitionCount();
//创建 XmlReaderContext 对象 加载注册 BeanDefinition
3documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
//记录加载BeanDefinition的个数
4return this.getRegistry().getBeanDefinitionCount() - countBefore;
}
(1)//通过类反射工具实例化BeanDefinitionDocumentReader对象
protected BeanDefinitionDocumentReader createBeanDefinitionDocumentReader() {
return (BeanDefinitionDocumentReader)BeanDefinitionDocumentReader.class.cast(BeanUtils.instantiateClass(this.documentReaderClass));
}
(2)在DefaultBeanDefinitionDocumentReader里找到实现得到配置文件root属性(注册)
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
this.logger.debug("Loading bean definitions");
Element root = doc.getDocumentElement();
this.doRegisterBeanDefinitions(root);
}
doRegisterBeanDefinitions方法(继续注册 真正的注册也是 解析元素)
protected void doRegisterBeanDefinitions(Element root) {
//BeanDefinitionParserDelegate 解析BeanDefinition
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.isInfoEnabled()) {
this.logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + this.getReaderContext().getResource());
}
return;
}
}
}
this.preProcessXml(root);
this.parseBeanDefinitions(root, this.delegate);
this.postProcessXml(root);
this.delegate = parent;
}
//解析beandefinition
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)) {//如果该节点使用默认命名空间,执行默认解析
this.parseDefaultElement(ele, delegate);
} else {
delegate.parseCustomElement(ele);//解析默认标签
}
}
}
} else {
delegate.parseCustomElement(root);//解析自定义标签
}
}
//解析默认标签
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if(delegate.nodeNameEquals(ele, "import")) {//解析import标签
this.importBeanDefinitionResource(ele);
} else if(delegate.nodeNameEquals(ele, "alias")) {//解析alias标签
this.processAliasRegistration(ele);
} else if(delegate.nodeNameEquals(ele, "bean")) {解析bean标签
this.processBeanDefinition(ele, delegate);
} else if(delegate.nodeNameEquals(ele, "beans")) {
this.doRegisterBeanDefinitions(ele);
}
}
默认标签bean的解析
bean标签解析
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
(1) BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
(2) bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);.//对自定义标签的解析
try {
// 对bdHolder进行注册
(3) 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));
}
}
(1)解析的过程中会创建承载bean属性的BeanDefinitaion
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
return parseBeanDefinitionElement(ele, null);
}
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
}
public AbstractBeanDefinition parseBeanDefinitionElement(){
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
}
protected AbstractBeanDefinition createBeanDefinition(String className, String parentName)
throws ClassNotFoundException {
return BeanDefinitionReaderUtils.createBeanDefinition( parentName, className, this.readerContext.getBeanClassLoader());
}
public static AbstractBeanDefinition createBeanDefinition(
String parentName, String className, ClassLoader classLoader) throws ClassNotFoundException {
GenericBeanDefinition bd = new GenericBeanDefinition();//进一步封装在GenericBeanDefinition中
bd.setParentName(parentName);
if (className != null) {
if (classLoader != null) {
bd.setBeanClass(ClassUtils.forName(className, classLoader));
}
else {
bd.setBeanClassName(className);
}
}
其中AbstractBeanDefinition bd类型已经变为GenericBeanDefinition类型
public class GenericBeanDefinition extends AbstractBeanDefinition
bd里面同过set方法存放了bean的各种子属性元素
(2)bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);//注册自定义的标签
解析了配置文件里面的各种标签下面就开始注册解析的BeanDefinition,也就是上面提过的
(3) BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any.
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String aliase : aliases) {
registry.registerAlias(beanName, aliase);
}
}
}
注意最终奥义BeanDefinitionRegistry 实现了注册beanDefinition()
完结。
可以通过名字和别名注册
(1)通过名字注册
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);
this.beanDefinitionMap.put(beanName, beanDefinition);//将beanName 和beanDefiniton放在map中
/*
具体实现看源码
*/
}
具体实现功能
BeanDefinition 的缓存也不是神奇的东西,就是定义一个 Map :
key
为beanName
。value
为 BeanDefinition 对象。
注册就是注册装有BeanDefinition 对象的map缓存中。
实现了BeanDefinitionRegistry接口中的
void registerBeanDefinition(String var1, BeanDefinition var2) throws BeanDefinitionStoreException;
Private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap(256);
this.beanDefinitionMap.put(beanName, beanDefinition);//bean注册真相
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ioc容器
- 在 IoC 容器内部维护着一个 BeanDefinition Map 的数据结构
- 在配置文件中每一个
<bean>
都对应着一个 BeanDefinition 对象。
-
注册。向 IoC 容器注册在第二步解析好的 BeanDefinition,这个过程是通过
-
-
-
-
接口来实现的。在 IoC 容器内部其实是将第二个过程解析得到的 BeanDefinition 注入到一个 HashMap 容器中,IoC 容器就是通过这个 HashMap 来维护这些 BeanDefinition 的。
- 在这里需要注意的一点是这个过程并没有完成依赖注入,依赖注册是发生在应用第一次调用
#getBean(...)
方法,向容器索要 Bean 时。 - 当然我们可以通过设置预处理,即对某个 Bean 设置
lazyinit = false
属性,那么这个 Bean 的依赖注入就会在容器初始化的时候完成。
注册beanDefiniiton的时候会解析标签默认标签和自定义标签
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.isInfoEnabled()) {
this.logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + this.getReaderContext().getResource());
}
return;
}
}
}
this.preProcessXml(root);
this.parseBeanDefinitions(root, this.delegate);
this.postProcessXml(root);
this.delegate = parent;
}
再次强调:
beandefiniiton中包含了一些配置文件中的一些标签属性
注册beandefiniiton就是 将beanDefiniton加入spring中ioc容器中
这里是解析资源文件的bean 默认标签
包扫描是解析自定义标签:
public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
String namespaceUri = this.getNamespaceURI(ele);//获取标签的命名空间
根据名称空间找到对应的NamespaceHandler
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 {
//标签解析
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
}
对于parse()方法
NamespaceHandlerSupport.java
public BeanDefinition parse(Element element, ParserContext parserContext) {
return this.findParserForElement(element, parserContext).parse(element, parserContext);
}
AbstractBeanDefinitionParser.java
public final BeanDefinition parse(Element element, ParserContext parserContext) {
AbstractBeanDefinition definition = this.parseInternal(element, parserContext);
}
protected final AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
String parentName = this.getParentName(element);
if(parentName != null) {
builder.getRawBeanDefinition().setParentName(parentName);
}
Class<?> beanClass = this.getBeanClass(element);
if(beanClass != null) {
builder.getRawBeanDefinition().setBeanClass(beanClass);
} else {
String beanClassName = this.getBeanClassName(element);
if(beanClassName != null) {
builder.getRawBeanDefinition().setBeanClassName(beanClassName);
}
}
builder.getRawBeanDefinition().setSource(parserContext.extractSource(element));
if(parserContext.isNested()) {
builder.setScope(parserContext.getContainingBeanDefinition().getScope());
}
if(parserContext.isDefaultLazyInit()) {
builder.setLazyInit(true);
}
this.doParse(element, parserContext, builder);
return builder.getBeanDefinition();
}