内容简介:spring mvc 扫描与注解
在mvc中扫描注解机制是我们理解javabean是怎么被加载,是如何被spring进行管理的第一步。那spring mvc 是如何扫描所有的编译文件并对注解进行操作的呢,下面我们来看下:
我们知道只要servlet中的load-on-startup配置了大于1的数字,类就会在应用启动的时候被加载,在加载时候是调用了DispatcherServlet 的init()方法。
但我们进入dispatcherServlet并没有找到init()方法,此时我们继续查找父类,在其父类的父类HttpServletBean这个类中找到了init()方法:
init方法中有一个initServletBean()方法,这个方法就是用来初始化javabean的。
在其子类,FrameworkServlet中我们看到了initServletBean方法的实现方法,其方法中有这样一行代码:
其实,只要获取到ApplicationContext就能获取到javabean信息,此时我们进去看下,其是如何初始化ApplicationContext的:
在FrameworkServlet中,标红代码创建了ApplicationContext,关于其中的parent参数,以后再说,继续跟进,在createWebApplicationContext方法中:
其实,不论是ClassPathXmlApplicationContext还是WEB装载都会调用这段方法,区别只是在于,web容器中,用servlet装载时,servlet包装了一个XmlWebApplicationContext而已,无论是ClassPathXmlApplicationContext还是XmlWebApplicationContext他们都继承自抽象类:AbstractApplicationContext,他们共用了AbstractApplicationContext的refresh()方法:
虽然这些一层调用一层看起来很烦,但还是希望大家有时间看下去,因为在spring-mvc装载bean的时候不仅要读取解析xml文件还要对class文件进行bean读取加载,并且在xml解析,类加载,实例化的过程中有很多需求,并且spring-mvc采用了分离设计,下面我们来看看obtainFreshBeanFactory()方法:
在obtainFreshBeanFactory()方法中,加载bean的是第一行refreshBeanFactory()方法,而不是getBeanFactory()方法。
关于refreshBeanFactory()的实现是在AbstractRefreshableApplicationContext类中实现了,它继承自AbstractApplicationContext同时,
ClassPathXmlApplicationContext与XmlWebApplicationContext也继承了AbstractRefreshableApplicationContext这个类
在第一行,他createBeanFactory,同时在loadBeanDefinitions(beanFactory)中加载bean并将bean放入了BeanFactory中,继续跟踪loadBeanDefinitions方法,它是由AbstractXmlApplicationContext类中的方法实现,web项目中会由XmlWebApplicationContext来实现,loadBeanDefinitions方法如下:
它通过XmlBeanDefinitionReader类去读取springXML中的信息(也就是解析SpringContext.xml)并加载bean,接下来会调用多层,并在XMLBeanDefinitionReader类中去调用doLoadBeanDefinitions、regiseterBeanDefinitions操作,在regiseterBeanDefinitions的时候就开始解析XML了。它调用了DefaultBeanDefinitionDocumentReader类的registerBeanDefinitions方法,如下图所示:
在这个方法中做了解析XML中的操作,看标红代码,这段代码做了bean的解析工作。跟踪进去会发现里面解析了XML的信息,其中NamespaceHanderSupport的parse方法会根据节点的类型,找到合适的解析(BeanDefinitionParse)方式,他们预先已经被注册号了,放在一个HashMap中,例如在Spring的annotation的注解扫描中,我们通常会配置:<context:component-scan base-package="com.xxx">,此时根据名称“component-scan”就会找到对应的解析器来解析,此时解析注解是用的ComponentScanBeanDefinitionParser的parse方法。
在parse获取到后,有一个关键的步骤就是定义了ClassPathBeanDefinitionScanner来扫描类信息来对class文件进行扫描:
这个方法中最重要的就是doScan方法的作用,那doScan方法是如何扫描的呢,这里可以跟踪进去一起看看:
我们先跟进去找到findCandidateComponents方法:
在此方法中通过标红代码获取路径,并取得了class文件,那么是怎么获取到class文件的呢,有兴趣的朋友可以将classpath路径写为:自己项目编译文件路径例如:classpath*:org/sinovate/**/*.class,并用如下操作:
在控制台输出resources信息便可以看到class文件路径名称信息等。在获取到.class路径以及文件名称后,我们就可以通过classLoaderListenser加载.class文件了,此时在根据Annotation类的方法就可以对@Controller,@Service,@Resource,等一系列注解进行控制与装载了。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Spring源码之注解扫描Component-scan
- 智能化扫描场景分析—精细化扫描SQL注入漏洞
- 漏洞扫描“全覆盖”法则 | 被动扫描如何在资产发现中发挥作用?
- 开源扫描仪的工具箱:安全行业从业人员自研开源扫描器合集
- MySQL -- 全表扫描
- 漏洞扫描
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
How to Build a Billion Dollar App
George Berkowski / Little, Brown Book Group / 2015-4-1 / USD 24.95
Apps have changed the way we communicate, shop, play, interact and travel and their phenomenal popularity has presented possibly the biggest business opportunity in history. In How to Build a Billi......一起来看看 《How to Build a Billion Dollar App》 这本书的介绍吧!