Insight task:annotation-driven 解析 | Insight 常识

原创 2016年07月28日 16:28:47

疑问:1、spring 配置<task:annotation-driven/>,容器启动过程中是怎样解析,做了哪些工作?

2、@Scheduled 是怎样find,解析,将注解的method 加入调度任务中?

...

注:Insight 版本3.2.13.RELEASE

首先明确的基本常识:

a.从spring的初始化开始,首先会根据xml 配置文件够造bean-factory,然后注册各种各样的bean-post-processor和bean-factory-post-processor,最后才是bean 的初始化。

b.配置文件的解析根据element namespace分为两部分实现:bean、import基础类的namespace默认内部实现,其他类型的namespace委托给各自的xxx-NameSpaceHandler实现。

c.bean初始化过程中涉及dependency 解析inject调用,递归进行bean初始化的过程,从而实现context中所有bean-definination的初始化。

...

ok,然后Insight code,可以解答问题1:

// 1、按照惯例,context 初始化入口,:)
AbstractApplicationContext.refresh()
// 2、定义beanFactory,真正的实现交给subClass
// application.xml 解析全部在此完成,
obtainFreshBeanFactory()
// 3、实现new beanFactory subClass来啦,此方法定义了一系列的步骤,其中loadBean 逻辑交给 subClass
AbstractRefreshableApplicationContext.refreshBeanFactory()
// 4、load application.xml Bean 真正实现
// Loads the bean definitions via an XmlBeanDefinitionReader.
XmlWebApplicationContext.loadBeanDefinitions()
// 5、!core Parse the elements. (default : "import", "alias", "bean")	
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
    // 判断namespace 是否属于 http://www.springframework.org/schema/beans
    if (delegate.isDefaultNamespace(root)) {
    	NodeList nl = root.getChildNodes();
    	for (int i = 0; i < nl.getLength(); i++) {
    		Node node = nl.item(i);
    		Element ele = (Element) node;
    		if (delegate.isDefaultNamespace(ele)) {
    			parseDefaultElement(ele, delegate);
    		}
    		else {
    		    // 我们的task:annotation-driven 就是从这里开始解析
    			delegate.parseCustomElement(ele);
    		}
    	}
    }
    // ...
}
// 6、对于customElement,按照惯例,委托给对应的Handler小弟们去实现解析。
// @see BeanDefinitionParserDelegate
public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
    String namespaceUri = getNamespaceURI(ele);
    // 根据element's namespace 获取对应的处理ClassName,通过反射newInstance()生成handler
    // ClassName:namespace mapping参考组件jar META-INF/spring.handlers
    NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
    if (handler == null) {
    	error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
    	return null;
    }
    return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
// 7、根据TaskNamespaceHandler终于找到主角AnnotationDrivenBeanDefinitionParser,解析
public BeanDefinition parse(Element element, ParserContext parserContext) {
    // ...
    // 注意ScheduledAnnotationBeanPostProcessor bean的初始化,@Scheduled 注解就是他解析的,后续讲到
    BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition("org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor");
    builder.getRawBeanDefinition().setSource(source);
    String scheduler = element.getAttribute("scheduler");
    if (StringUtils.hasText(scheduler)) {
    	builder.addPropertyReference("scheduler", scheduler);
    }
    registerPostProcessor(parserContext, builder, AnnotationConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME);
    // ...

}
// 8、Finally 解析完毕,解析@Scheduled 注解的Processor准备,注册完毕。
// happy ending.../**
 * http://www.springframework.org/schema/task Custom解析器
 * 实现  解析 
 * (其中)
 * 
 * @author Mark Fisher
 * @since 3.0
 */
public class TaskNamespaceHandler extends NamespaceHandlerSupport {
    
    // 该方法在Locate NameSpaceHandler过程中调用。@see DefaultNamespaceHandlerResolver.resolve()
	public void init() {
		this.registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
		this.registerBeanDefinitionParser("executor", new ExecutorBeanDefinitionParser());
		this.registerBeanDefinitionParser("scheduled-tasks", new ScheduledTasksBeanDefinitionParser());
		this.registerBeanDefinitionParser("scheduler", new SchedulerBeanDefinitionParser());
	}

}

总结:AnnotationDrivenBeanDefinitionParser 实现<task:annotation-driven/>解析,解析的过程可以直接跳过Insight,直接看parse() 即可。

对于问题2,parse过程中注册了PostProcessor,待bean初始化完成后,会触发post事件,ScheduledAnnotationBeanPostProcessor就会上场,find @Scheduled method,完成Scheduled 的解析,下回Insight。


版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tt50335971/article/details/52055755

Insight Windows Azure

带你了解Windows Azure,同时了解常用Windows Azure 问题处理
  • 2016年04月11日 17:30

Spring注解配置定时任务<task:annotation-driven/>

首先在配置文件头部的必须要有:xmlns:task="http://www.springframework.org/schema/task"其次xsi:schemaLocation必须为其添加:htt...
  • wow4464
  • wow4464
  • 2016-03-21 12:03:40
  • 22340

spring3使用task注记及task:annotation-driven解决定时问题

转载自:http://blog.csdn.net/guoquanyou/article/details/6756437 最近发现真的凹凸了,Spring升级到3后原来已经自带任务调度器了,之前还一直...
  • a1124544556
  • a1124544556
  • 2016-12-26 11:59:41
  • 5181

annotation-config, annotation-driven, compont-scan 区别

本文开门见山,直接分别进行解释: **一、** 隐式地向Spring容器中注册AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPo...
  • catoop
  • catoop
  • 2015-11-27 12:14:07
  • 5766

Spring 4.x Task 和 Schedule 概述

转载请注明 https://zhangzhaoyu.github.io/2016/09/30/spring-task-and-schedule-deep-research/ 摘要在很多业务场景中,系...
  • TRAMP_ZZY
  • TRAMP_ZZY
  • 2016-09-30 22:52:31
  • 7611

Spring注解形式的定时任务配置详解(转)

一 SpringContext.xml中添加以下配置 1. beans添加xmlns:task ? 1 xmlns:task="ht...
  • abc86319253
  • abc86319253
  • 2014-10-21 20:45:16
  • 3124

Spring task quartz 定时任务的几种实现

 Spring定时任务的几种实现 近日项目开发中需要执行一些定时任务,比如需要在每天凌晨时候,分析一次前一天的日志信息,借此机会整理了一下定时任务的几种实现方式,由于项目采用spring框架,...
  • wilsonke
  • wilsonke
  • 2014-05-22 15:22:57
  • 31981

spring2.5报出tx:annotation-driven is not bound异常解决方法

今天配置spring 是碰到tx:annotation-driven is not bound 的问题,这个错误的原因很简单是: 我们在定义申明AOP的时候。。没有加载schema。 具体...
  • ljgllxyz
  • ljgllxyz
  • 2012-09-24 10:20:18
  • 3817

Spring MVC 解读——<mvc:annotation-driven/>

Spring MVC 解读—— 一、AnnotationDrivenBeanDefinitionParser       原文地址:http://my.oschina.net/HeliosFl...
  • qq_30747531
  • qq_30747531
  • 2016-08-02 19:07:15
  • 557

目标检测资源汇总

转载自重要网站:https://handong1587.github.io/deep_learning/2015/10/09/object-detection.html#t-cnn ...
  • Julialove102123
  • Julialove102123
  • 2018-01-12 11:18:12
  • 1204
收藏助手
不良信息举报
您举报文章:Insight task:annotation-driven 解析 | Insight 常识
举报原因:
原因补充:

(最多只允许输入30个字)