Spring启动过程写的过于冗杂,若是对于这部分不感兴趣能够直接跳到Dubbo和Spring的关系,依然可以愉快的阅读。java
第一步:node
ClassPathXmlApplicationContext的构造方法:spring
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
private Resource[] configResources;
// 若是已经有 ApplicationContext 并须要配置成父子关系,那么调用这个构造方法
public ClassPathXmlApplicationContext(ApplicationContext parent) {
super(parent);
}
...
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {
super(parent);
// 根据提供的路径,处理成配置文件数组(以分号、逗号、空格、tab、换行符分割)
setConfigLocations(configLocations);
if (refresh) {
refresh(); // 核心方法
}
}
...
}
复制代码
接下来,就是refresh(),将原来的ApplicationContext销毁,而后从新执行一次初始化操做。express
@Override
public void refresh() throws BeansException, IllegalStateException {
// 来个锁,否则 refresh() 还没结束,你又来个启动或销毁容器的操做,那不就乱套了嘛
synchronized (this.startupShutdownMonitor) {
// 准备工做,记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符
prepareRefresh();
// 这步比较关键,这步完成后,配置文件就会解析成一个个 Bean 定义,注册到 BeanFactory 中,
// 固然,这里说的 Bean 尚未初始化,只是配置信息都提取出来了,
// 注册也只是将这些信息都保存到了注册中心(说到底核心是一个 beanName-> beanDefinition 的 map)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean
// 这块待会会展开说
prepareBeanFactory(beanFactory);
try {
// 【这里须要知道 BeanFactoryPostProcessor 这个知识点,Bean 若是实现了此接口,
// 那么在容器初始化之后,Spring 会负责调用里面的 postProcessBeanFactory 方法。】
// 这里是提供给子类的扩展点,到这里的时候,全部的 Bean 都加载、注册完成了,可是都尚未初始化
// 具体的子类能够在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或作点什么事
postProcessBeanFactory(beanFactory);
// 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法
invokeBeanFactoryPostProcessors(beanFactory);
// 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
// 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
// 两个方法分别在 Bean 初始化以前和初始化以后获得执行。注意,到这里 Bean 还没初始化
registerBeanPostProcessors(beanFactory);
// 初始化当前 ApplicationContext 的 MessageSource,国际化这里就不展开说了,否则没完没了了
initMessageSource();
// 初始化当前 ApplicationContext 的事件广播器,这里也不展开了
initApplicationEventMulticaster();
// 从方法名就能够知道,典型的模板方法(钩子方法),
// 具体的子类能够在这里初始化一些特殊的 Bean(在初始化 singleton beans 以前)
onRefresh();
// 注册事件监听器,监听器须要实现 ApplicationListener 接口。这也不是咱们的重点,过
registerListeners();
// 重点,重点,重点
// 初始化全部的 singleton beans
//(lazy-init 的除外)
finishBeanFactoryInitialization(beanFactory);
// 最后,广播事件,ApplicationContext 初始化完成
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
// 销毁已经初始化的 singleton 的 Beans,以避免有些 bean 会一直占用资源
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// 把异常往外抛
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
复制代码
建立Bean容器前的准备工做:apache
protected void prepareRefresh() {
// 记录启动时间,
// 将 active 属性设置为 true,closed 属性设置为 false,它们都是 AtomicBoolean 类型
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
// Initialize any placeholder property sources in the context environment
initPropertySources();
// 校验 xml 配置文件
getEnvironment().validateRequiredProperties();
this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
}
复制代码
建立Bean容器,加载并注册Bean数组
这里会初始化BeanFactory、加载Bean、注册Bean等等。bash
AbstractApplicationContext.javaapp
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//关闭就得BeanFactory,建立新的BeanFactory,加载Bean定义、注册Bean等等。
this.refreshBeanFactory();
//返回刚刚建立的BeanFactory
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
if (this.logger.isDebugEnabled()) {
this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
复制代码
AbstractRefreshableApplicationContext.java 120框架
@Override
protected final void refreshBeanFactory() throws BeansException {
// 若是 ApplicationContext 中已经加载过 BeanFactory 了,销毁全部 Bean,关闭 BeanFactory
// 注意,应用中 BeanFactory 原本就是能够多个的,这里可不是说应用全局是否有 BeanFactory,而是当前
// ApplicationContext 是否有 BeanFactory
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// 初始化一个 DefaultListableBeanFactory,为何用这个,咱们立刻说。
DefaultListableBeanFactory beanFactory = createBeanFactory();
// 用于 BeanFactory 的序列化,我想不部分人应该都用不到
beanFactory.setSerializationId(getId());
// 下面这两个方法很重要,别跟丢了,具体细节以后说
// 设置 BeanFactory 的两个配置属性:是否容许 Bean 覆盖、是否容许循环引用
customizeBeanFactory(beanFactory);
// 加载 Bean 到 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);
}
}
复制代码
customizeBeanFactory(beanFactory)less
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
if (this.allowBeanDefinitionOverriding != null) {
// 是否容许 Bean 定义覆盖
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
if (this.allowCircularReferences != null) {
// 是否容许 Bean 间的循环依赖
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
}
复制代码
AbstractXmlApplicationContext.java 80 loadBeanDefinitions(beanFactory)
/** 咱们能够看到,此方法将经过一个 XmlBeanDefinitionReader 实例来加载各个 Bean。*/
@Override
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));
// 初始化 BeanDefinitionReader,其实这个是提供给子类覆写的,
// 我看了一下,没有类覆写这个方法,咱们姑且当作不重要吧
initBeanDefinitionReader(beanDefinitionReader);
// 重点来了,继续往下
loadBeanDefinitions(beanDefinitionReader);
}
复制代码
如今还在这个类中,接下来用刚刚初始化的 Reader 开始来加载 xml 配置,这块代码读者能够选择性跳过,不是很重要。也就是说,下面这个代码块,读者能够很轻松地略过。
// AbstractXmlApplicationContext.java 120
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = getConfigResources();
if (configResources != null) {
// 往下看
reader.loadBeanDefinitions(configResources);
}
String[] configLocations = getConfigLocations();
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations);
}
}
// 上面虽然有两个分支,不过第二个分支很快经过解析路径转换为 Resource 之后也会进到这里
@Override
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
Assert.notNull(resources, "Resource array must not be null");
int counter = 0;
// 注意这里是个 for 循环,也就是每一个文件是一个 resource
for (Resource resource : resources) {
// 继续往下看
counter += loadBeanDefinitions(resource);
}
return counter;
}
// XmlBeanDefinitionReader 303
@Override
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
return loadBeanDefinitions(new EncodedResource(resource));
}
// XmlBeanDefinitionReader 314
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (logger.isInfoEnabled()) {
logger.info("Loading XML bean definitions from " + encodedResource.getResource());
}
// 用一个 ThreadLocal 来存放全部的配置文件资源
Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
if (currentResources == null) {
currentResources = new HashSet<EncodedResource>(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
}
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
}
try {
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
// 核心部分
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
finally {
inputStream.close();
}
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"IOException parsing XML document from " + encodedResource.getResource(), ex);
}
finally {
currentResources.remove(encodedResource);
if (currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
}
// 还在这个文件中,第 388 行
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
try {
// 这里就不看了
Document doc = doLoadDocument(inputSource, resource);
// 继续
return registerBeanDefinitions(doc, resource);
}
catch (...
}
// 还在这个文件中,第 505 行
// 返回从当前配置文件加载了多少数量的 Bean
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
int countBefore = getRegistry().getBeanDefinitionCount();
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}
// DefaultBeanDefinitionDocumentReader 90
@Override
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
logger.debug("Loading bean definitions");
Element root = doc.getDocumentElement();
doRegisterBeanDefinitions(root);
}
复制代码
通过漫长的链路,一个配置文件终于转换为一颗DOM树了,注意,这里指的是其中一个配置文件,不是全部。下面从根节点开始解析:
doRegisterBeanDefinitions:
// DefaultBeanDefinitionDocumentReader 116
protected void doRegisterBeanDefinitions(Element root) {
// 咱们看名字就知道,BeanDefinitionParserDelegate 一定是一个重要的类,它负责解析 Bean 定义,
// 这里为何要定义一个 parent? 看到后面就知道了,是递归问题,
// 由于 <beans /> 内部是能够定义 <beans /> 的,因此这个方法的 root 其实不必定就是 xml 的根节点,也能够是嵌套在里面的 <beans /> 节点,从源码分析的角度,咱们当作根节点就行了
BeanDefinitionParserDelegate parent = this.delegate;
this.delegate = createDelegate(getReaderContext(), root, parent);
if (this.delegate.isDefaultNamespace(root)) {
// 这块说的是根节点 <beans ... profile="dev" /> 中的 profile 是不是当前环境须要的,
// 若是当前环境配置的 profile 不包含此 profile,那就直接 return 了,不对此 <beans /> 解析
// 不熟悉 profile 为什么物,不熟悉怎么配置 profile 读者的请移步附录区
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;
}
}
}
preProcessXml(root); // 钩子
parseBeanDefinitions(root, this.delegate);
postProcessXml(root); // 钩子
this.delegate = parent;
}
复制代码
接下来,看核心解析方法parseBeanDefinitions(roo,this.delegate):
// default namespace 涉及到的就四个标签 <import />、<alias />、<bean /> 和 <beans />,
// 其余的属于 custom 的
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)) {
parseDefaultElement(ele, delegate);
}
else {
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
复制代码
从上面的代码,咱们能够看到,对于每一个配置来讲,分别进入到 parseDefaultElement(ele, delegate); 和 delegate.parseCustomElement(ele); 这两个分支了。
parseDefaultElement(ele, delegate) 表明解析的节点是 <import />
、<alias />
、<bean />
、<beans />
这几个。
这里的四个标签之因此是 default 的,是由于它们是处于这个 namespace 下定义的:
http://www.springframework.org/schema/beans
复制代码
回过神来,看看处理 default 标签的方法:
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
// 处理 <import /> 标签
importBeanDefinitionResource(ele);
}
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
// 处理 <alias /> 标签订义
// <alias name="fromName" alias="toName"/>
processAliasRegistration(ele);
}
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
// 处理 <bean /> 标签订义,这也算是咱们的重点吧
processBeanDefinition(ele, delegate);
}
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// 若是碰到的是嵌套的 <beans /> 标签,须要递归
doRegisterBeanDefinitions(ele);
}
}
复制代码
若是每一个标签都说,那我不吐血,大家都要吐血了。咱们挑咱们的重点 <bean />
标签出来讲。
processBeanDefinition
下面是 processBeanDefinition 解析 <bean />
标签:
// DefaultBeanDefinitionDocumentReader 298
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// 将 <bean /> 节点中的信息提取出来,而后封装到一个 BeanDefinitionHolder 中,细节往下看
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));
}
}
复制代码
继续往下看怎么解析以前,咱们先看下 标签中能够定义哪些属性:
Property | |
---|---|
class | 类的全限定名 |
name | 可指定 id、name(用逗号、分号、空格分隔) |
scope | 做用域 |
constructor arguments | 指定构造参数 |
properties | 设置属性的值 |
autowiring mode | no(默认值)、byName、byType、 constructor |
lazy-initialization mode | 是否懒加载(若是被非懒加载的bean依赖了那么其实也就不能懒加载了) |
initialization method | bean 属性设置完成后,会调用这个方法 |
destruction method | bean 销毁后的回调方法 |
上面表格中的内容我想你们都很是熟悉吧,若是不熟悉,那就是你不够了解 Spring 的配置了。
简单地说就是像下面这样子:
<bean id="exampleBean" name="name1, name2, name3" class="com.javadoop.ExampleBean" scope="singleton" lazy-init="true" init-method="init" destroy-method="cleanup">
<!-- 能够用下面三种形式指定构造参数 -->
<constructor-arg type="int" value="7500000"/>
<constructor-arg name="years" value="7500000"/>
<constructor-arg index="0" value="7500000"/>
<!-- property 的几种状况 -->
<property name="beanOne">
<ref bean="anotherExampleBean"/>
</property>
<property name="beanTwo" ref="yetAnotherBean"/>
<property name="integerProperty" value="1"/>
</bean>
复制代码
固然,除了上面举例出来的这些,还有 factory-bean、factory-method、<lockup-method />
、<replaced-method />
、<meta />
、<qualifier />
这几个,你们是否是熟悉呢?
有了以上这些知识之后,咱们再继续往里看怎么解析 bean 元素,是怎么转换到 BeanDefinitionHolder 的。
// BeanDefinitionParserDelegate 428
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
return parseBeanDefinitionElement(ele, null);
}
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
String id = ele.getAttribute(ID_ATTRIBUTE);
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
List<String> aliases = new ArrayList<String>();
// 将 name 属性的定义按照 ”逗号、分号、空格“ 切分,造成一个别名列表数组,
// 固然,若是你不定义的话,就是空的了
// 我在附录中简单介绍了一下 id 和 name 的配置,你们能够看一眼,有个20秒就能够了
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
aliases.addAll(Arrays.asList(nameArr));
}
String beanName = id;
// 若是没有指定id, 那么用别名列表的第一个名字做为beanName
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);
}
// 根据 <bean ...>...</bean> 中的配置建立 BeanDefinition,而后把配置中的信息都设置到实例中,
// 细节后面再说
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
// 到这里,整个 <bean /> 标签就算解析结束了,一个 BeanDefinition 就造成了。
if (beanDefinition != null) {
// 若是都没有设置 id 和 name,那么此时的 beanName 就会为 null,进入下面这块代码产生
// 若是读者不感兴趣的话,我以为不须要关心这块代码,对本文源码分析来讲,这些东西不重要
if (!StringUtils.hasText(beanName)) {
try {
if (containingBean != null) {// 按照咱们的思路,这里 containingBean 是 null 的
beanName = BeanDefinitionReaderUtils.generateBeanName(
beanDefinition, this.readerContext.getRegistry(), true);
}
else {
// 若是咱们不定义 id 和 name,那么咱们引言里的那个例子:
// 1. beanName 为:com.javadoop.example.MessageServiceImpl#0
// 2. beanClassName 为:com.javadoop.example.MessageServiceImpl
beanName = this.readerContext.generateBeanName(beanDefinition);
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName != null &&
beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
// 把 beanClassName 设置为 Bean 的别名
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;
}
复制代码
看看怎么根据配置建立 BeanDefinition:
public AbstractBeanDefinition parseBeanDefinitionElement( Element ele, String beanName, BeanDefinition containingBean) {
this.parseState.push(new BeanEntry(beanName));
String className = null;
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
}
try {
String parent = null;
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
// 建立 BeanDefinition,而后设置类信息而已,很简单,就不贴代码了
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
// 设置 BeanDefinition 的一堆属性,这些属性定义在 AbstractBeanDefinition 中
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
/** * 下面的一堆是解析 <bean>......</bean> 内部的子元素, * 解析出来之后的信息都放到 bd 的属性中 */
// 解析 <meta />
parseMetaElements(ele, bd);
// 解析 <lookup-method />
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
// 解析 <replaced-method />
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
// 解析 <constructor-arg />
parseConstructorArgElements(ele, bd);
// 解析 <property />
parsePropertyElements(ele, bd);
// 解析 <qualifier />
parseQualifierElements(ele, bd);
bd.setResource(this.readerContext.getResource());
bd.setSource(extractSource(ele));
return bd;
}
catch (ClassNotFoundException ex) {
error("Bean class [" + className + "] not found", ele, ex);
}
catch (NoClassDefFoundError err) {
error("Class that bean class [" + className + "] depends on not found", ele, err);
}
catch (Throwable ex) {
error("Unexpected failure during bean definition parsing", ele, ex);
}
finally {
this.parseState.pop();
}
return null;
}
复制代码
到这里,咱们已经完成了根据 <bean />
配置建立了一个 BeanDefinitionHolder 实例。注意,是一个。
咱们回到解析 <bean />
的入口方法:
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// 将 <bean /> 节点转换为 BeanDefinitionHolder,就是上面说的一堆
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
// 若是有自定义属性的话,进行相应的解析,先忽略
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// 咱们把这步叫作 注册Bean 吧
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// 注册完成后,发送事件,本文不展开说这个
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
复制代码
你们再仔细看一下这块吧,咱们后面就不回来讲这个了。这里已经根据一个 <bean />
标签产生了一个 BeanDefinitionHolder 的实例,这个实例里面也就是一个 BeanDefinition 的实例和它的 beanName、aliases 这三个信息,注意,咱们的关注点始终在 BeanDefinition 上:
public class BeanDefinitionHolder implements BeanMetadataElement {
private final BeanDefinition beanDefinition;
private final String beanName;
private final String[] aliases;
...
复制代码
而后咱们准备注册这个 BeanDefinition,最后,把这个注册事件发送出去。
下面,咱们开始说注册 Bean 吧。
注册 Bean
// BeanDefinitionReaderUtils 143
public static void registerBeanDefinition( BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
String beanName = definitionHolder.getBeanName();
// 注册这个 Bean
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// 若是还有别名的话,也要根据别名通通注册一遍,否则根据别名就找不到 Bean 了,这咱们就不开心了
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
// alias -> beanName 保存它们的别名信息,这个很简单,用一个 map 保存一下就能够了,
// 获取的时候,会先将 alias 转换为 beanName,而后再查找
registry.registerAlias(beanName, alias);
}
}
}
复制代码
别名注册的放一边,毕竟它很简单,咱们看看怎么注册 Bean。
// DefaultListableBeanFactory 793
@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 {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(...);
}
}
// old? 还记得 “容许 bean 覆盖” 这个配置吗?allowBeanDefinitionOverriding
BeanDefinition oldBeanDefinition;
// 以后会看到,全部的 Bean 注册后会放入这个 beanDefinitionMap 中
oldBeanDefinition = this.beanDefinitionMap.get(beanName);
// 处理重复名称的 Bean 定义的状况
if (oldBeanDefinition != null) {
if (!isAllowBeanDefinitionOverriding()) {
// 若是不容许覆盖的话,抛异常
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription()...
}
else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
// log...用框架定义的 Bean 覆盖用户自定义的 Bean
}
else if (!beanDefinition.equals(oldBeanDefinition)) {
// log...用新的 Bean 覆盖旧的 Bean
}
else {
// log...用同等的 Bean 覆盖旧的 Bean,这里指的是 equals 方法返回 true 的 Bean
}
// 覆盖
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
// 判断是否已经有其余的 Bean 开始初始化了.
// 注意,"注册Bean" 这个动做结束,Bean 依然尚未初始化,咱们后面会有大篇幅说初始化过程,
// 在 Spring 容器启动的最后,会 预初始化 全部的 singleton beans
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<String>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
if (this.manualSingletonNames.contains(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
}
else {
// 最正常的应该是进到这里。
// 将 BeanDefinition 放到这个 map 中,这个 map 保存了全部的 BeanDefinition
this.beanDefinitionMap.put(beanName, beanDefinition);
// 这是个 ArrayList,因此会按照 bean 配置的顺序保存每个注册的 Bean 的名字
this.beanDefinitionNames.add(beanName);
// 这是个 LinkedHashSet,表明的是手动注册的 singleton bean,
// 注意这里是 remove 方法,到这里的 Bean 固然不是手动注册的
// 手动指的是经过调用如下方法注册的 bean :
// registerSingleton(String beanName, Object singletonObject)
// 这不是重点,解释只是为了避免让你们疑惑。Spring 会在后面"手动"注册一些 Bean,如 "environment"、"systemProperties" 等 bean
this.manualSingletonNames.remove(beanName);
}
// 这个不重要,在预初始化的时候会用到,没必要管它。
this.frozenBeanDefinitionNames = null;
}
if (oldBeanDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
复制代码
Bean 容器实例化完成后
说到这里,咱们回到 refresh() 方法,我从新贴了一遍代码,看看咱们说到哪了。是的,咱们才说完 obtainFreshBeanFactory() 方法。
考虑到篇幅,这里开始大幅缩减掉不必详细介绍的部分,你们直接看下面的代码中的注释就行了。
@Override
public void refresh() throws BeansException, IllegalStateException {
// 来个锁,否则 refresh() 还没结束,你又来个启动或销毁容器的操做,那不就乱套了嘛
synchronized (this.startupShutdownMonitor) {
// 准备工做,记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符
prepareRefresh();
// 这步比较关键,这步完成后,配置文件就会解析成一个个 Bean 定义,注册到 BeanFactory 中,
// 固然,这里说的 Bean 尚未初始化,只是配置信息都提取出来了,
// 注册也只是将这些信息都保存到了注册中心(说到底核心是一个 beanName-> beanDefinition 的 map)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean
// 这块待会会展开说
prepareBeanFactory(beanFactory);
try {
// 【这里须要知道 BeanFactoryPostProcessor 这个知识点,Bean 若是实现了此接口,
// 那么在容器初始化之后,Spring 会负责调用里面的 postProcessBeanFactory 方法。】
// 这里是提供给子类的扩展点,到这里的时候,全部的 Bean 都加载、注册完成了,可是都尚未初始化
// 具体的子类能够在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或作点什么事
postProcessBeanFactory(beanFactory);
// 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法
invokeBeanFactoryPostProcessors(beanFactory);
// 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
// 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
// 两个方法分别在 Bean 初始化以前和初始化以后获得执行。注意,到这里 Bean 还没初始化
registerBeanPostProcessors(beanFactory);
// 初始化当前 ApplicationContext 的 MessageSource,国际化这里就不展开说了,否则没完没了了
initMessageSource();
// 初始化当前 ApplicationContext 的事件广播器,这里也不展开了
initApplicationEventMulticaster();
// 从方法名就能够知道,典型的模板方法(钩子方法),
// 具体的子类能够在这里初始化一些特殊的 Bean(在初始化 singleton beans 以前)
onRefresh();
// 注册事件监听器,监听器须要实现 ApplicationListener 接口。这也不是咱们的重点,过
registerListeners();
// 重点,重点,重点
// 初始化全部的 singleton beans
//(lazy-init 的除外)
finishBeanFactoryInitialization(beanFactory);
// 最后,广播事件,ApplicationContext 初始化完成
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
// 销毁已经初始化的 singleton 的 Beans,以避免有些 bean 会一直占用资源
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// 把异常往外抛
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
复制代码
准备 Bean 容器: prepareBeanFactory
这里简单介绍下 prepareBeanFactory(factory) 方法:
/** * Configure the factory's standard context characteristics, * such as the context's ClassLoader and post-processors. * @param beanFactory the BeanFactory to configure */
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 设置 BeanFactory 的类加载器,咱们知道 BeanFactory 须要加载类,也就须要类加载器,
// 这里设置为当前 ApplicationContext 的类加载器
beanFactory.setBeanClassLoader(getClassLoader());
// 设置 BeanExpressionResolver
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 添加一个 BeanPostProcessor,这个 processor 比较简单,
// 实现了 Aware 接口的几个特殊的 beans 在初始化的时候,这个 processor 负责回调
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 下面几行的意思就是,若是某个 bean 依赖于如下几个接口的实现类,在自动装配的时候忽略它们,
// Spring 会经过其余方式来处理这些依赖。
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
/** * 下面几行就是为特殊的几个 bean 赋值,若是有 bean 依赖了如下几个,会注入这边相应的值, * 以前咱们说过,"当前 ApplicationContext 持有一个 BeanFactory",这里解释了第一行 * ApplicationContext 继承了 ResourceLoader、ApplicationEventPublisher、MessageSource * 因此对于这几个,能够赋值为 this,注意 this 是一个 ApplicationContext * 那这里怎么没看到为 MessageSource 赋值呢?那是由于 MessageSource 被注册成为了一个普通的 bean */
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 这个 BeanPostProcessor 也很简单,在 bean 实例化后,若是是 ApplicationListener 的子类,
// 那么将其添加到 listener 列表中,能够理解成:注册事件监听器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
// 这里涉及到特殊的 bean,名为:loadTimeWeaver,这不是咱们的重点,忽略它
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()));
}
/** * 从下面几行代码咱们能够知道,Spring 每每很 "智能" 就是由于它会帮咱们默认注册一些有用的 bean, * 咱们也能够选择覆盖 */
// 若是没有定义 "environment" 这个 bean,那么 Spring 会 "手动" 注册一个
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
// 若是没有定义 "systemProperties" 这个 bean,那么 Spring 会 "手动" 注册一个
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
// 若是没有定义 "systemEnvironment" 这个 bean,那么 Spring 会 "手动" 注册一个
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
复制代码
初始化全部的 singleton beans
咱们的重点固然是 finishBeanFactoryInitialization(beanFactory); 这个巨头了,这里会负责初始化全部的 singleton beans。
注意,后面的描述中,我都会使用初始化或预初始化来表明这个阶段。主要是 Spring 须要在这个阶段完成全部的 singleton beans 的实例化。
咱们来总结一下,到目前为止,应该说 BeanFactory 已经建立完成,而且全部的实现了 BeanFactoryPostProcessor 接口的 Bean 都已经初始化而且其中的 postProcessBeanFactory(factory) 方法已经获得执行了。全部实现了 BeanPostProcessor 接口的 Bean 也都完成了初始化。
剩下的就是初始化其余还没被初始化的 singleton beans 了,咱们知道它们是单例的,若是没有设置懒加载,那么 Spring 会在接下来初始化全部的 singleton beans。
// AbstractApplicationContext.java 834
// 初始化剩余的 singleton beans
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 什么,看代码这里没有初始化 Bean 啊!
// 注意了,初始化的动做包装在 beanFactory.getBean(...) 中,这里先不说细节,先往下看吧
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
return getEnvironment().resolvePlaceholders(strVal);
}
});
}
// 先初始化 LoadTimeWeaverAware 类型的 Bean
// 通常用于织入第三方模块,在 class 文件载入 JVM 的时候动态织入,这里不展开说
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// 没什么别的目的,由于到这一步的时候,Spring 已经开始预初始化 singleton beans 了,
// 确定不但愿这个时候还出现 bean 定义解析、加载、注册。
beanFactory.freezeConfiguration();
// 开始初始化剩下的
beanFactory.preInstantiateSingletons();
}
复制代码
从上面最后一行往里看,咱们又回到 DefaultListableBeanFactory 这个类了,这个类你们应该都不陌生了吧。
preInstantiateSingletons
// DefaultListableBeanFactory 728
@Override
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
// 触发全部的非懒加载的 singleton beans 的初始化操做
for (String beanName : beanNames) {
// 合并父 Bean 中的配置,注意 <bean id="" class="" parent="" /> 中的 parent,用的很少吧,
// 考虑到这可能会影响你们的理解,我在附录中解释了一下 "Bean 继承",请移步
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 非抽象、非懒加载的 singletons。若是配置了 'abstract = true',那是不须要初始化的
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 处理 FactoryBean(读者若是不熟悉 FactoryBean,请移步附录区了解)
if (isFactoryBean(beanName)) {
// FactoryBean 的话,在 beanName 前面加上 ‘&’ 符号。再调用 getBean,getBean 方法别急
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
// 判断当前 FactoryBean 是不是 SmartFactoryBean 的实现,此处忽略,直接跳过
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
// 对于普通的 Bean,只要调用 getBean(beanName) 这个方法就能够进行初始化了
getBean(beanName);
}
}
}
// 到这里说明全部的非懒加载的 singleton beans 已经完成了初始化
// 若是咱们定义的 bean 是实现了 SmartInitializingSingleton 接口的,那么在这里获得回调,忽略
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
smartSingleton.afterSingletonsInstantiated();
return null;
}
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
复制代码
接下来,咱们就进入到 getBean(beanName) 方法了,这个方法咱们常常用来从 BeanFactory 中获取一个 Bean,而初始化的过程也封装到了这个方法里。
getBean
在继续前进以前,读者应该具有 FactoryBean 的知识,若是读者还不熟悉,请移步附录部分了解 FactoryBean。
// AbstractBeanFactory 196
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
// 咱们在剖析初始化 Bean 的过程,可是 getBean 方法咱们常常是用来从容器中获取 Bean 用的,注意切换思路,
// 已经初始化过了就从容器中直接返回,不然就先初始化再返回
@SuppressWarnings("unchecked")
protected <T> T doGetBean( final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
// 获取一个 “正统的” beanName,处理两种状况,一个是前面说的 FactoryBean(前面带 ‘&’),
// 一个是别名问题,由于这个方法是 getBean,获取 Bean 用的,你要是传一个别名进来,是彻底能够的
final String beanName = transformedBeanName(name);
// 注意跟着这个,这个是返回值
Object bean;
// 检查下是否是已经建立过了
Object sharedInstance = getSingleton(beanName);
// 这里说下 args 呗,虽然看上去一点不重要。前面咱们一路进来的时候都是 getBean(beanName),
// 因此 args 实际上是 null 的,可是若是 args 不为空的时候,那么意味着调用方不是但愿获取 Bean,而是建立 Bean
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("...");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 下面这个方法:若是是普通 Bean 的话,直接返回 sharedInstance,
// 若是是 FactoryBean 的话,返回它建立的那个实例对象
// (FactoryBean 知识,读者若不清楚请移步附录)
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
if (isPrototypeCurrentlyInCreation(beanName)) {
// 当前线程已经建立过了此 beanName 的 prototype 类型的 bean,那么抛异常
throw new BeanCurrentlyInCreationException(beanName);
}
// 检查一下这个 BeanDefinition 在容器中是否存在
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 若是当前容器不存在这个 BeanDefinition,试试父容器中有没有
String nameToLookup = originalBeanName(name);
if (args != null) {
// 返回父容器的查询结果
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCheckOnly) {
// typeCheckOnly 为 false,将当前 beanName 放入一个 alreadyCreated 的 Set 集合中。
markBeanAsCreated(beanName);
}
/* * 稍稍总结一下: * 到这里的话,要准备建立 Bean 了,对于 singleton 的 Bean 来讲,容器中还没建立过此 Bean; * 对于 prototype 的 Bean 来讲,原本就是要建立一个新的 Bean。 */
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 先初始化依赖的全部 Bean,这个很好理解。
// 注意,这里的依赖指的是 depends-on 中定义的依赖
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// 检查是否是有循环依赖,这里的循环依赖和咱们前面说的循环依赖又不同,这里确定是不容许出现的,否则要乱套了,读者想一下就知道了
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 注册一下依赖关系
registerDependentBean(dep, beanName);
// 先初始化被依赖项
getBean(dep);
}
}
// 建立 singleton 的实例
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
// 执行建立 Bean,详情后面再说
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 建立 prototype 的实例
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
// 执行建立 Bean
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// 若是不是 singleton 和 prototype 的话,须要委托给相应的实现类来处理
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
// 执行建立 Bean
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// 最后,检查一下类型对不对,不对的话就抛异常,对的话就返回了
if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
try {
return getTypeConverter().convertIfNecessary(bean, requiredType);
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
复制代码
你们应该也猜到了,接下来固然是分析 createBean 方法:
protected abstract Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException;
复制代码
第三个参数 args 数组表明建立实例须要的参数,不就是给构造方法用的参数,或者是工厂 Bean 的参数嘛,不过要注意,在咱们的初始化阶段,args 是 null。
这回咱们要到一个新的类了 AbstractAutowireCapableBeanFactory,看类名,AutowireCapable?类名是否是也说明了点问题了。
主要是为了如下场景,采用 @Autowired 注解注入属性值:
public class MessageServiceImpl implements MessageService {
@Autowired
private UserService userService;
public String getMessage() {
return userService.getMessage();
}
}
复制代码
<bean id="messageService" class="com.javadoop.example.MessageServiceImpl" />
复制代码
// AbstractAutowireCapableBeanFactory 447
/** * Central method of this class: creates a bean instance, * populates the bean instance, applies post-processors, etc. * @see #doCreateBean */
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 确保 BeanDefinition 中的 Class 被加载
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 准备方法覆写,这里又涉及到一个概念:MethodOverrides,它来自于 bean 定义中的 <lookup-method />
// 和 <replaced-method />,若是读者感兴趣,回到 bean 解析的地方看看对这两个标签的解析。
// 我在附录中也对这两个标签的相关知识点进行了介绍,读者能够移步去看看
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// 让 BeanPostProcessor 在这一步有机会返回代理,而不是 bean 实例,
// 要完全了解清楚这个,须要去看 InstantiationAwareBeanPostProcessor 接口,这里就不展开说了
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
// 重头戏,建立 bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
复制代码
建立 Bean
往里看 doCreateBean 这个方法:
/** * Actually create the specified bean. Pre-creation processing has already happened * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks. * <p>Differentiates between default bean instantiation, use of a * factory method, and autowiring a constructor. * @param beanName the name of the bean * @param mbd the merged bean definition for the bean * @param args explicit arguments to use for constructor or factory method invocation * @return a new instance of the bean * @throws BeanCreationException if the bean could not be created * @see #instantiateBean * @see #instantiateUsingFactoryMethod * @see #autowireConstructor */
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 说明不是 FactoryBean,这里实例化 Bean,这里很是关键,细节以后再说
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 这个就是 Bean 里面的 咱们定义的类 的实例,不少地方我描述成 "bean 实例"
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
// 类型
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
// 建议跳过吧,涉及接口:MergedBeanDefinitionPostProcessor
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// MergedBeanDefinitionPostProcessor,这个我真不展开说了,直接跳过吧,不多用的
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// 下面这块代码是为了解决循环依赖的问题,之后有时间,我再对循环依赖这个问题进行解析吧
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 这一步也是很是关键的,这一步负责属性装配,由于前面的实例只是实例化了,并无设值,这里就是设值
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
// 还记得 init-method 吗?还有 InitializingBean 接口?还有 BeanPostProcessor 接口?
// 这里就是处理 bean 初始化完成后的各类回调
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
//
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
复制代码
到这里,咱们已经分析完了 doCreateBean 方法,总的来讲,咱们已经说完了整个初始化流程。
接下来咱们挑 doCreateBean 中的三个细节出来讲说。一个是建立 Bean 实例的 createBeanInstance 方法,一个是依赖注入的 populateBean 方法,还有就是回调方法 initializeBean。
注意了,接下来的这三个方法要认真说那也是极其复杂的,不少地方我就点到为止了,感兴趣的读者能够本身往里看,最好就是碰到不懂的,本身写代码去调试它。
建立 Bean 实例
咱们先看看 createBeanInstance 方法。须要说明的是,这个方法若是每一个分支都分析下去,必然也是极其复杂冗长的,咱们挑重点说。此方法的目的就是实例化咱们指定的类。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
// 确保已经加载了此 class
Class<?> beanClass = resolveBeanClass(mbd, beanName);
// 校验一下这个类的访问权限
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
if (mbd.getFactoryMethodName() != null) {
// 采用工厂方法实例化,不熟悉这个概念的读者请看附录,注意,不是 FactoryBean
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 若是不是第一次建立,好比第二次建立 prototype bean。
// 这种状况下,咱们能够从第一次建立知道,采用无参构造函数,仍是构造函数依赖注入 来完成实例化
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
// 构造函数依赖注入
return autowireConstructor(beanName, mbd, null, null);
}
else {
// 无参构造函数
return instantiateBean(beanName, mbd);
}
}
// 判断是否采用有参构造函数
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 构造函数依赖注入
return autowireConstructor(beanName, mbd, ctors, args);
}
// 调用无参构造函数
return instantiateBean(beanName, mbd);
}
复制代码
挑个简单的无参构造函数构造实例来看看:
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
return getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
}, getAccessControlContext());
}
else {
// 实例化
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
// 包装一下,返回
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
复制代码
咱们能够看到,关键的地方在于:
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
复制代码
这里会进行实际的实例化过程,咱们进去看看:
// SimpleInstantiationStrategy 59
@Override
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
// 若是不存在方法覆写,那就使用 java 反射进行实例化,不然使用 CGLIB,
// 方法覆写 请参见附录"方法注入"中对 lookup-method 和 replaced-method 的介绍
if (bd.getMethodOverrides().isEmpty()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
@Override
public Constructor<?> run() throws Exception {
return clazz.getDeclaredConstructor((Class[]) null);
}
});
}
else {
constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
// 利用构造方法进行实例化
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// 存在方法覆写,利用 CGLIB 来完成实例化,须要依赖于 CGLIB 生成子类,这里就不展开了
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
复制代码
到这里,咱们就算实例化完成了。咱们开始说怎么进行属性注入。
bean 属性注入
// AbstractAutowireCapableBeanFactory 1203
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
// bean 实例的全部属性都在这里了
PropertyValues pvs = mbd.getPropertyValues();
if (bw == null) {
if (!pvs.isEmpty()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
// 到这步的时候,bean 实例化完成(经过工厂方法或构造方法),可是还没开始属性设值,
// InstantiationAwareBeanPostProcessor 的实现类能够在这里对 bean 进行状态修改,
// 我也没找到有实际的使用,因此咱们暂且忽略这块吧
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 若是返回 false,表明不须要进行后续的属性设值,也不须要再通过其余的 BeanPostProcessor 的处理
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 经过名字找到全部属性值,若是是 bean 依赖,先初始化依赖的 bean。记录依赖关系
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 经过类型装配。复杂一些
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 这里有个很是有用的 BeanPostProcessor 进到这里: AutowiredAnnotationBeanPostProcessor
// 对采用 @Autowired、@Value 注解的依赖进行设值,这里的内容也是很是丰富的,不过本文不会展开说了,感兴趣的读者请自行研究
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
// 设置 bean 实例的属性值
applyPropertyValues(beanName, mbd, bw, pvs);
}
复制代码
initializeBean
属性注入完成后,这一步其实就是处理各类回调了。
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
// 若是 bean 实现了 BeanNameAware、BeanClassLoaderAware 或 BeanFactoryAware 接口,回调
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// BeanPostProcessor 的 postProcessBeforeInitialization 回调
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 处理 bean 中定义的 init-method,
// 或者若是 bean 实现了 InitializingBean 接口,调用 afterPropertiesSet() 方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// BeanPostProcessor 的 postProcessAfterInitialization 回调
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
复制代码
你们发现没有,BeanPostProcessor 的两个回调都发生在这边,只不过中间处理了 init-method,是否是和读者原来的认知有点不同了?
首先咱们来看一下官方demo中给出的Dubbo启动代码:
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo-demo-provider.xml"});
context.start();
System.in.read(); // press any key to exit
}
复制代码
再看一下配置文件:
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!-- provider's application name, used for tracing dependency relationship -->
<dubbo:application name="demo-provider"/>
<!-- use multicast registry center to export service -->
<dubbo:registry address="zookeeper://47.107.231.174:2181"/>
<!-- use dubbo protocol to export service on port 20880 -->
<dubbo:protocol name="dubbo" port="20880"/>
<!-- service implementation, as same as regular local bean -->
<bean id="demoService" class="org.apache.dubbo.demo.provider.DemoServiceImpl"/>
<!-- declare the service interface to be exported -->
<dubbo:service interface="org.apache.dubbo.demo.DemoService" ref="demoService"/>
</beans>
复制代码
能够看到Dubbo启动的代码很简单,只有三行,经过构建ClassPathXmlApplicationContext来启动Dubbo。那么Dubbo是如何在ClassPathXmlApplicationContext构建过程当中实现本身的相关逻辑的呢?
在Dubbo的官方文档中是这样写的:
基于 dubbo.jar 内的
META-INF/spring.handlers
配置,Spring 在遇到 dubbo 名称空间时,会回调DubboNamespaceHandler
。全部 dubbo 的标签,都统一用
DubboBeanDefinitionParser
进行解析,基于一对一属性映射,将 XML 标签解析为 Bean 对象。
这里提到的spring.handlers配置以下:
http\://dubbo.apache.org/schema/dubbo=org.apache.dubbo.config.spring.schema.DubboNamespaceHandler
http\://code.alibabatech.com/schema/dubbo=org.apache.dubbo.config.spring.schema.DubboNamespaceHandler
复制代码
这里的两个配置对应了Dubbo从阿里开源到捐赠apache的过程。
咱们来看一下Spring中是如何解析Dubbo的配置文件的:
这是在启动Dubbo过程当中解析文件的调用链路
能够看到开始启动以后
执行ClassPathXmlApplicationContext的构造方法,在构造方法中调用refresh构造新的ApplicationContext对象,在这里会加载BeanDefiniton。也就是说会加载咱们在Dubbo的配置文件中的相关配置。
在执行解析对应的Element对象时,会进入BeanDefinitionParserDelegate.class的parseCustomElement方法:
public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
String namespaceUri = this.getNamespaceURI(ele);//首先得到对应的namespaceUri,这里对应的namaspaceUri是http://dubbo.apche.org/schema/dubbo
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);//根据namespaceUri获取对应的Handler
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));//handler执行相应的解析逻辑,最后跳转到DubboBeanDefinitionParser执行parse方法。
}
}
复制代码
DefaultNamespaceHandlerResolver.class类:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.springframework.beans.factory.xml;
import java.io.IOException;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.FatalBeanException;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
public class DefaultNamespaceHandlerResolver implements NamespaceHandlerResolver {
public static final String DEFAULT_HANDLER_MAPPINGS_LOCATION = "META-INF/spring.handlers";//默认的handler配置文件地址
protected final Log logger;
private final ClassLoader classLoader;
private final String handlerMappingsLocation;
private volatile Map<String, Object> handlerMappings;//namespaceUri和解析器实例的映射关系
public DefaultNamespaceHandlerResolver() {
this((ClassLoader)null, "META-INF/spring.handlers");
}
public DefaultNamespaceHandlerResolver(ClassLoader classLoader) {
this(classLoader, "META-INF/spring.handlers");
}
public DefaultNamespaceHandlerResolver(ClassLoader classLoader, String handlerMappingsLocation) {
this.logger = LogFactory.getLog(this.getClass());
Assert.notNull(handlerMappingsLocation, "Handler mappings location must not be null");
this.classLoader = classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader();
this.handlerMappingsLocation = handlerMappingsLocation;
}
public NamespaceHandler resolve(String namespaceUri) {
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 {
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 {
NamespaceHandler namespaceHandler = (NamespaceHandler)BeanUtils.instantiateClass(handlerClass);//建立对应Handler的实例
namespaceHandler.init();//建立以后调用init方法
handlerMappings.put(namespaceUri, namespaceHandler);//添加到对应map中
return namespaceHandler;
}
} catch (ClassNotFoundException var7) {
throw new FatalBeanException("NamespaceHandler class [" + className + "] for namespace [" + namespaceUri + "] not found", var7);
} catch (LinkageError var8) {
throw new FatalBeanException("Invalid NamespaceHandler class [" + className + "] for namespace [" + namespaceUri + "]: problem with handler class file or dependent class", var8);
}
}
}
//当须要得到对应的namespaceUri和handler的映射关系时,使用双重检查锁来构造handlerMapping。
private Map<String, Object> getHandlerMappings() {
if (this.handlerMappings == null) {
synchronized(this) {
if (this.handlerMappings == null) {
try {
Properties mappings = PropertiesLoaderUtils.loadAllProperties(this.handlerMappingsLocation, this.classLoader);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Loaded NamespaceHandler mappings: " + mappings);
}
Map<String, Object> handlerMappings = new ConcurrentHashMap(mappings.size());
CollectionUtils.mergePropertiesIntoMap(mappings, handlerMappings);
this.handlerMappings = handlerMappings;
} catch (IOException var5) {
throw new IllegalStateException("Unable to load NamespaceHandler mappings from location [" + this.handlerMappingsLocation + "]", var5);
}
}
}
}
return this.handlerMappings;
}
public String toString() {
return "NamespaceHandlerResolver using mappings " + this.getHandlerMappings();
}
}
复制代码
从上面的类中咱们了解到handler和namespaceUri的对应关系默认是从META-INF/spring.handlers文件中读取,这就是为何咱们只须要在META-INF/spring.handlers配置对应的解析器,spring就能自动的使用相应的解析去解析对应的名称空间下的Element对象。
从上面能够看到建立了对应的Handler实例以后,会调用该handler的init方法。
DubboNamespaceHandler.java的init方法以下:
@Override
public void init() {
registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
registerBeanDefinitionParser("annotation", new AnnotationBeanDefinitionParser());
}
复制代码
在init方法中,对dubbo中不一样的实体注册了不一样的解析器,并指定不一样的名称解析成不一样的实体对象。若是后续还须要什么新的实体添加,只须要在这个地方添加对应的解析器就能够。
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd)):这里会执行DubboBeanDefinitionParser中的parser方法:
private static BeanDefinition parse(Element element, ParserContext parserContext, Class<?> beanClass, boolean required) {
//建立RootBeanDefinition
RootBeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setBeanClass(beanClass);
beanDefinition.setLazyInit(false);
//解析配置对象的id。若不存在,则进行生成
String id = element.getAttribute("id");
if ((id == null || id.length() == 0) && required) {
String generatedBeanName = element.getAttribute("name");
if (generatedBeanName == null || generatedBeanName.length() == 0) {
if (ProtocolConfig.class.equals(beanClass)) {
generatedBeanName = "dubbo";
} else {
generatedBeanName = element.getAttribute("interface");
}
}
if (generatedBeanName == null || generatedBeanName.length() == 0) {
generatedBeanName = beanClass.getName();
}
id = generatedBeanName;
//若id已存在,经过自增序列,解决重复
int counter = 2;
while (parserContext.getRegistry().containsBeanDefinition(id)) {
id = generatedBeanName + (counter++);
}
}
if (id != null && id.length() > 0) {
if (parserContext.getRegistry().containsBeanDefinition(id)) {
throw new IllegalStateException("Duplicate spring bean id " + id);
}
//添加到Spring的注册表
parserContext.getRegistry().registerBeanDefinition(id, beanDefinition);
//设置Bean的'id'属性值
beanDefinition.getPropertyValues().addPropertyValue("id", id);
}
//处理<dubbo:protocol/>特殊状况
if (ProtocolConfig.class.equals(beanClass)) {
for (String name : parserContext.getRegistry().getBeanDefinitionNames()) {
BeanDefinition definition = parserContext.getRegistry().getBeanDefinition(name);
PropertyValue property = definition.getPropertyValues().getPropertyValue("protocol");
if (property != null) {
Object value = property.getValue();
if (value instanceof ProtocolConfig && id.equals(((ProtocolConfig) value).getName())) {
definition.getPropertyValues().addPropertyValue("protocol", new RuntimeBeanReference(id));
}
}
}
//处理<dubbo:service/>的class的属性
} else if (ServiceBean.class.equals(beanClass)) {
String className = element.getAttribute("class");
if (className != null && className.length() > 0) {
RootBeanDefinition classDefinition = new RootBeanDefinition();
classDefinition.setBeanClass(ReflectUtils.forName(className));
classDefinition.setLazyInit(false);
parseProperties(element.getChildNodes(), classDefinition);
beanDefinition.getPropertyValues().addPropertyValue("ref", new BeanDefinitionHolder(classDefinition, id + "Impl"));
}
//解析<dubbo:provider/>的内嵌子元素<dubbo:service/>
} else if (ProviderConfig.class.equals(beanClass)) {
parseNested(element, parserContext, ServiceBean.class, true, "service", "provider", id, beanDefinition);
//解析<dubbo:consumer/>的内嵌子元素<dubbo:reference>
} else if (ConsumerConfig.class.equals(beanClass)) {
parseNested(element, parserContext, ReferenceBean.class, false, "reference", "consumer", id, beanDefinition);
}
Set<String> props = new HashSet<String>();
ManagedMap parameters = null;
//循环Bean对象的setting方法,将属性赋值到Bean对象
for (Method setter : beanClass.getMethods()) {
String name = setter.getName();
//判断是不是set方法
if (name.length() > 3 && name.startsWith("set")
&& Modifier.isPublic(setter.getModifiers())
&& setter.getParameterTypes().length == 1) {
Class<?> type = setter.getParameterTypes()[0];
//添加'props'
String property = StringUtils.camelToSplitName(name.substring(3, 4).toLowerCase() + name.substring(4), "-");
props.add(property);
Method getter = null;
//getting&&public&&属性值类型统一
try {
getter = beanClass.getMethod("get" + name.substring(3), new Class<?>[0]);
} catch (NoSuchMethodException e) {
try {
getter = beanClass.getMethod("is" + name.substring(3), new Class<?>[0]);
} catch (NoSuchMethodException e2) {
}
}
if (getter == null
|| !Modifier.isPublic(getter.getModifiers())
|| !type.equals(getter.getReturnType())) {
continue;
}
//解析'<dubbo:parameters/>'
if ("parameters".equals(property)) {
parameters = parseParameters(element.getChildNodes(), beanDefinition);
//解析<dubbo:method>
} else if ("methods".equals(property)) {
parseMethods(id, element.getChildNodes(), beanDefinition, parserContext);
//解析'<dubbo:argument>'
} else if ("arguments".equals(property)) {
parseArguments(id, element.getChildNodes(), beanDefinition, parserContext);
} else {
String value = element.getAttribute(property);
if (value != null) {
value = value.trim();
if (value.length() > 0) {
//不想注册到注册中心的状况
if ("registry".equals(property) && RegistryConfig.NO_AVAILABLE.equalsIgnoreCase(value)) {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setAddress(RegistryConfig.NO_AVAILABLE);
beanDefinition.getPropertyValues().addPropertyValue(property, registryConfig);
} else if ("registry".equals(property) && value.indexOf(',') != -1) {
//多注册中心的状况
parseMultiRef("registries", value, beanDefinition, parserContext);
} else if ("provider".equals(property) && value.indexOf(',') != -1) {
//多服务提供者的状况
parseMultiRef("providers", value, beanDefinition, parserContext);
} else if ("protocol".equals(property) && value.indexOf(',') != -1) {
//多协议的状况
parseMultiRef("protocols", value, beanDefinition, parserContext);
} else {
Object reference;
//处理属性为基本属性的状况
if (isPrimitive(type)) {
//兼容性处理
if ("async".equals(property) && "false".equals(value)
|| "timeout".equals(property) && "0".equals(value)
|| "delay".equals(property) && "0".equals(value)
|| "version".equals(property) && "0.0.0".equals(value)
|| "stat".equals(property) && "-1".equals(value)
|| "reliable".equals(property) && "false".equals(value)) {
// backward compatibility for the default value in old version's xsd
value = null;
}
reference = value;
//处理在'<dubbo:provider/>'或者<dubbo:service/>上定义了'protocol'属性的兼容性
} else if ("protocol".equals(property)
&& ExtensionLoader.getExtensionLoader(Protocol.class).hasExtension(value)
&& (!parserContext.getRegistry().containsBeanDefinition(value)//存在该注册表的实现
|| !ProtocolConfig.class.getName().equals(parserContext.getRegistry().getBeanDefinition(value).getBeanClassName()))) {
//目前,<dubbo:provider protocol=""/>推荐独立成<dubbo:protocol/>
if ("dubbo:provider".equals(element.getTagName())) {
logger.warn("Recommended replace <dubbo:provider protocol=\"" + value + "\" ... /> to <dubbo:protocol name=\"" + value + "\" ... />");
}
// backward compatibility
ProtocolConfig protocol = new ProtocolConfig();
protocol.setName(value);
reference = protocol;
//处理onreturn属性
} else if ("onreturn".equals(property)) {
//按照'.'拆分
int index = value.lastIndexOf(".");
String returnRef = value.substring(0, index);
String returnMethod = value.substring(index + 1);
//建立RuntimeBeanReference,指向回调对象
reference = new RuntimeBeanReference(returnRef);
//设置'onreturnMethod'到BeanDefinition的属性值
beanDefinition.getPropertyValues().addPropertyValue("onreturnMethod", returnMethod);
//处理onthrow属性
} else if ("onthrow".equals(property)) {
//按照'.'拆分
int index = value.lastIndexOf(".");
String throwRef = value.substring(0, index);
String throwMethod = value.substring(index + 1);
//建立RuntimeBeanReference指向回调对象
reference = new RuntimeBeanReference(throwRef);
//设置’onthrowMethod‘到BeanDefinition的属性值
beanDefinition.getPropertyValues().addPropertyValue("onthrowMethod", throwMethod);
} else if ("oninvoke".equals(property)) {
int index = value.lastIndexOf(".");
String invokeRef = value.substring(0, index);
String invokeRefMethod = value.substring(index + 1);
reference = new RuntimeBeanReference(invokeRef);
beanDefinition.getPropertyValues().addPropertyValue("oninvokeMethod", invokeRefMethod);
} else {
//指向Service的bean对象,必须是单例
if ("ref".equals(property) && parserContext.getRegistry().containsBeanDefinition(value)) {
BeanDefinition refBean = parserContext.getRegistry().getBeanDefinition(value);
if (!refBean.isSingleton()) {
throw new IllegalStateException("The exported service ref " + value + " must be singleton! Please set the " + value + " bean scope to singleton, eg: <bean id=\"" + value + "\" scope=\"singleton\" ...>");
}
}
//建立RuntimeBeanReference,指向service的Bean对象
reference = new RuntimeBeanReference(value);
}
//设置BeanDefinition的属性值
beanDefinition.getPropertyValues().addPropertyValue(property, reference);
}
}
}
}
}
}
//将XML元素,未在上面遍历到的属性添加到'parameters'集合中。
NamedNodeMap attributes = element.getAttributes();
int len = attributes.getLength();
for (int i = 0; i < len; i++) {
Node node = attributes.item(i);
String name = node.getLocalName();
if (!props.contains(name)) {
if (parameters == null) {
parameters = new ManagedMap();
}
String value = node.getNodeValue();
parameters.put(name, new TypedStringValue(value, String.class));
}
}
if (parameters != null) {
beanDefinition.getPropertyValues().addPropertyValue("parameters", parameters);
}
return beanDefinition;
}
复制代码
这里Dubbo的配置文件解析就告一段落。
最后就是如何实如今Dubbo启动的时候讲服务注册到注册中心上去,这里就须要用到前面解析的对象。在前面咱们提到DubboBeanDefinitionParser会将service解析为ServiceBean对象。
咱们先看看ServiceBean类的实现:
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
package org.apache.dubbo.config.spring;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ModuleConfig;
import org.apache.dubbo.config.MonitorConfig;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.ProviderConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;
import org.apache.dubbo.config.annotation.Service;
import org.apache.dubbo.config.spring.extension.SpringExtensionFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.support.AbstractApplicationContext;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/** * ServiceFactoryBean * * @export */
public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener<ContextRefreshedEvent>, BeanNameAware {
private static final long serialVersionUID = 213195494150089726L;
private final transient Service service;
private transient ApplicationContext applicationContext;
private transient String beanName;
private transient boolean supportedApplicationListener;
public ServiceBean() {
super();
this.service = null;
}
public ServiceBean(Service service) {
super(service);
this.service = service;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
SpringExtensionFactory.addApplicationContext(applicationContext);
try {
Method method = applicationContext.getClass().getMethod("addApplicationListener", ApplicationListener.class); // backward compatibility to spring 2.0.1
method.invoke(applicationContext, this);
supportedApplicationListener = true;
} catch (Throwable t) {
if (applicationContext instanceof AbstractApplicationContext) {
try {
Method method = AbstractApplicationContext.class.getDeclaredMethod("addListener", ApplicationListener.class); // backward compatibility to spring 2.0.1
if (!method.isAccessible()) {
method.setAccessible(true);
}
method.invoke(applicationContext, this);
supportedApplicationListener = true;
} catch (Throwable t2) {
}
}
}
}
@Override
public void setBeanName(String name) {
this.beanName = name;
}
/** * Gets associated {@link Service} * * @return associated {@link Service} */
public Service getService() {
return service;
}
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if (isDelay() && !isExported() && !isUnexported()) {
if (logger.isInfoEnabled()) {
logger.info("The service ready on spring started. service: " + getInterface());
}
export();
}
}
private boolean isDelay() {
Integer delay = getDelay();
ProviderConfig provider = getProvider();
if (delay == null && provider != null) {
delay = provider.getDelay();
}
return supportedApplicationListener && (delay == null || delay == -1);
}
@Override
@SuppressWarnings({"unchecked", "deprecation"})
public void afterPropertiesSet() throws Exception {
if (getProvider() == null) {
Map<String, ProviderConfig> providerConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProviderConfig.class, false, false);
if (providerConfigMap != null && providerConfigMap.size() > 0) {
Map<String, ProtocolConfig> protocolConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.class, false, false);
if ((protocolConfigMap == null || protocolConfigMap.size() == 0)
&& providerConfigMap.size() > 1) { // backward compatibility
List<ProviderConfig> providerConfigs = new ArrayList<ProviderConfig>();
for (ProviderConfig config : providerConfigMap.values()) {
if (config.isDefault() != null && config.isDefault()) {
providerConfigs.add(config);
}
}
if (!providerConfigs.isEmpty()) {
setProviders(providerConfigs);
}
} else {
ProviderConfig providerConfig = null;
for (ProviderConfig config : providerConfigMap.values()) {
if (config.isDefault() == null || config.isDefault()) {
if (providerConfig != null) {
throw new IllegalStateException("Duplicate provider configs: " + providerConfig + " and " + config);
}
providerConfig = config;
}
}
if (providerConfig != null) {
setProvider(providerConfig);
}
}
}
}
if (getApplication() == null
&& (getProvider() == null || getProvider().getApplication() == null)) {
Map<String, ApplicationConfig> applicationConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ApplicationConfig.class, false, false);
if (applicationConfigMap != null && applicationConfigMap.size() > 0) {
ApplicationConfig applicationConfig = null;
for (ApplicationConfig config : applicationConfigMap.values()) {
if (config.isDefault() == null || config.isDefault()) {
if (applicationConfig != null) {
throw new IllegalStateException("Duplicate application configs: " + applicationConfig + " and " + config);
}
applicationConfig = config;
}
}
if (applicationConfig != null) {
setApplication(applicationConfig);
}
}
}
if (getModule() == null
&& (getProvider() == null || getProvider().getModule() == null)) {
Map<String, ModuleConfig> moduleConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ModuleConfig.class, false, false);
if (moduleConfigMap != null && moduleConfigMap.size() > 0) {
ModuleConfig moduleConfig = null;
for (ModuleConfig config : moduleConfigMap.values()) {
if (config.isDefault() == null || config.isDefault()) {
if (moduleConfig != null) {
throw new IllegalStateException("Duplicate module configs: " + moduleConfig + " and " + config);
}
moduleConfig = config;
}
}
if (moduleConfig != null) {
setModule(moduleConfig);
}
}
}
if ((getRegistries() == null || getRegistries().isEmpty())
&& (getProvider() == null || getProvider().getRegistries() == null || getProvider().getRegistries().isEmpty())
&& (getApplication() == null || getApplication().getRegistries() == null || getApplication().getRegistries().isEmpty())) {
Map<String, RegistryConfig> registryConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, RegistryConfig.class, false, false);
if (registryConfigMap != null && registryConfigMap.size() > 0) {
List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>();
for (RegistryConfig config : registryConfigMap.values()) {
if (config.isDefault() == null || config.isDefault()) {
registryConfigs.add(config);
}
}
if (!registryConfigs.isEmpty()) {
super.setRegistries(registryConfigs);
}
}
}
if (getMonitor() == null
&& (getProvider() == null || getProvider().getMonitor() == null)
&& (getApplication() == null || getApplication().getMonitor() == null)) {
Map<String, MonitorConfig> monitorConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, MonitorConfig.class, false, false);
if (monitorConfigMap != null && monitorConfigMap.size() > 0) {
MonitorConfig monitorConfig = null;
for (MonitorConfig config : monitorConfigMap.values()) {
if (config.isDefault() == null || config.isDefault()) {
if (monitorConfig != null) {
throw new IllegalStateException("Duplicate monitor configs: " + monitorConfig + " and " + config);
}
monitorConfig = config;
}
}
if (monitorConfig != null) {
setMonitor(monitorConfig);
}
}
}
if ((getProtocols() == null || getProtocols().isEmpty())
&& (getProvider() == null || getProvider().getProtocols() == null || getProvider().getProtocols().isEmpty())) {
Map<String, ProtocolConfig> protocolConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.class, false, false);
if (protocolConfigMap != null && protocolConfigMap.size() > 0) {
List<ProtocolConfig> protocolConfigs = new ArrayList<ProtocolConfig>();
for (ProtocolConfig config : protocolConfigMap.values()) {
if (config.isDefault() == null || config.isDefault()) {
protocolConfigs.add(config);
}
}
if (!protocolConfigs.isEmpty()) {
super.setProtocols(protocolConfigs);
}
}
}
if (getPath() == null || getPath().length() == 0) {
if (beanName != null && beanName.length() > 0
&& getInterface() != null && getInterface().length() > 0
&& beanName.startsWith(getInterface())) {
setPath(beanName);
}
}
if (!isDelay()) {
export();
}
}
@Override
public void destroy() throws Exception {
// This will only be called for singleton scope bean, and expected to be called by spring shutdown hook when BeanFactory/ApplicationContext destroys.
// We will guarantee dubbo related resources being released with dubbo shutdown hook.
//unexport();
}
// merged from dubbox
@Override
protected Class getServiceClass(T ref) {
if (AopUtils.isAopProxy(ref)) {
return AopUtils.getTargetClass(ref);
}
return super.getServiceClass(ref);
}
}
复制代码
能够看到ServiceBean继承了ServiceConfig类,实现了InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener, BeanNameAware。
InitializingBean
只包括afterPropertiesSet()方法,继承该接口的类,在初始化bean的时候会执行该方法。在构造方法以后调用。
DisposableBean
DisposableBean也是一个接口,提供了一个惟一的方法destory()。在Bean生命周期结束前调用destory()方法作一些收尾工做.
init-method destory-method
@PostConstruct 和 @PreDestroy
Constructor >> @Autowired >> @PostConstruct
ApplicationContextAware
Spring容器会检测容器中的全部Bean,若是发现某个Bean实现了ApplicationContextAware接口,Spring容器会在建立该Bean以后,自动调用该Bean的setApplicationContextAware()方法,调用该方法时,会将容器自己做为参数传给该方法
ApplicationListener
当Spring容器初始化完成以后,会发布一个ContextRefreshedEvent事件,实现ApplicationListener接口的类,会调用*onApplicationEvent(E event)*方法。
BeanNameAware
public void setBeanName(String beanName) {
this.beanName = beanName;
}
得到本身的名字
BeanFactoryAware
让Bean获取配置他们的BeanFactory的引用。
在Spring注册完成以后会调用finishRefresh方法,在该方法中会调用实现了ApplicationListenner类的onApplicationEvent方法。
public void onApplicationEvent(ContextRefreshedEvent event) {
if (isDelay() && !isExported() && !isUnexported()) {
if (logger.isInfoEnabled()) {
logger.info("The service ready on spring started. service: " + getInterface());
}
export();
}
}
复制代码
ServiceBean的OnApplicationEvent方法如上,能够看到在该方法中调用了export实现了服务的注册。
再看一看ReferenceBean的实现:
public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean, ApplicationContextAware, InitializingBean, DisposableBean {
private static final long serialVersionUID = 213195494150089726L;
private transient ApplicationContext applicationContext;
public ReferenceBean() {
super();
}
public ReferenceBean(Reference reference) {
super(reference);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
SpringExtensionFactory.addApplicationContext(applicationContext);
}
@Override
public Object getObject() {
return get();
}
@Override
public Class<?> getObjectType() {
return getInterfaceClass();
}
@Override
@Parameter(excluded = true)
public boolean isSingleton() {
return true;
}
@Override
@SuppressWarnings({"unchecked"})
public void afterPropertiesSet() throws Exception {
if (getConsumer() == null) {
Map<String, ConsumerConfig> consumerConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ConsumerConfig.class, false, false);
if (consumerConfigMap != null && consumerConfigMap.size() > 0) {
ConsumerConfig consumerConfig = null;
for (ConsumerConfig config : consumerConfigMap.values()) {
if (config.isDefault() == null || config.isDefault()) {
if (consumerConfig != null) {
throw new IllegalStateException("Duplicate consumer configs: " + consumerConfig + " and " + config);
}
consumerConfig = config;
}
}
if (consumerConfig != null) {
setConsumer(consumerConfig);
}
}
}
if (getApplication() == null
&& (getConsumer() == null || getConsumer().getApplication() == null)) {
Map<String, ApplicationConfig> applicationConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ApplicationConfig.class, false, false);
if (applicationConfigMap != null && applicationConfigMap.size() > 0) {
ApplicationConfig applicationConfig = null;
for (ApplicationConfig config : applicationConfigMap.values()) {
if (config.isDefault() == null || config.isDefault()) {
if (applicationConfig != null) {
throw new IllegalStateException("Duplicate application configs: " + applicationConfig + " and " + config);
}
applicationConfig = config;
}
}
if (applicationConfig != null) {
setApplication(applicationConfig);
}
}
}
if (getModule() == null
&& (getConsumer() == null || getConsumer().getModule() == null)) {
Map<String, ModuleConfig> moduleConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ModuleConfig.class, false, false);
if (moduleConfigMap != null && moduleConfigMap.size() > 0) {
ModuleConfig moduleConfig = null;
for (ModuleConfig config : moduleConfigMap.values()) {
if (config.isDefault() == null || config.isDefault()) {
if (moduleConfig != null) {
throw new IllegalStateException("Duplicate module configs: " + moduleConfig + " and " + config);
}
moduleConfig = config;
}
}
if (moduleConfig != null) {
setModule(moduleConfig);
}
}
}
if ((getRegistries() == null || getRegistries().isEmpty())
&& (getConsumer() == null || getConsumer().getRegistries() == null || getConsumer().getRegistries().isEmpty())
&& (getApplication() == null || getApplication().getRegistries() == null || getApplication().getRegistries().isEmpty())) {
Map<String, RegistryConfig> registryConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, RegistryConfig.class, false, false);
if (registryConfigMap != null && registryConfigMap.size() > 0) {
List<RegistryConfig> registryConfigs = new ArrayList<>();
for (RegistryConfig config : registryConfigMap.values()) {
if (config.isDefault() == null || config.isDefault()) {
registryConfigs.add(config);
}
}
if (!registryConfigs.isEmpty()) {
super.setRegistries(registryConfigs);
}
}
}
if (getMonitor() == null
&& (getConsumer() == null || getConsumer().getMonitor() == null)
&& (getApplication() == null || getApplication().getMonitor() == null)) {
Map<String, MonitorConfig> monitorConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, MonitorConfig.class, false, false);
if (monitorConfigMap != null && monitorConfigMap.size() > 0) {
MonitorConfig monitorConfig = null;
for (MonitorConfig config : monitorConfigMap.values()) {
if (config.isDefault() == null || config.isDefault()) {
if (monitorConfig != null) {
throw new IllegalStateException("Duplicate monitor configs: " + monitorConfig + " and " + config);
}
monitorConfig = config;
}
}
if (monitorConfig != null) {
setMonitor(monitorConfig);
}
}
}
Boolean b = isInit();
if (b == null && getConsumer() != null) {
b = getConsumer().isInit();
}
if (b != null && b) {
getObject();
}
}
@Override
public void destroy() {
// do nothing
}
}
复制代码
在ReferenceBean中是经过FactoryBean来实现消费服务去注册中心拉取相应的服务,创建对应的proxy的。