2019-03-13 14:56:37 1144浏览
今天扣丁学堂Java培训老师给大家分享一篇关于Spring的初始化和XML解析实现详解,首先Spring是什么?它是一个应用程序框架,为应用程序的开发提供强大的支持,例如对事务处理和持久化的支持等;它也是一个bean容器,管理bean对象的整个生命周期,维护bean的各种存在状态,例如bean对象的实例化、销毁、bean的单实例和多实例状态等。
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
String[] configLocations = getConfigLocations();
if (configLocations != null) {
for (String configLocation : configLocations) {
reader.loadBeanDefinitions(configLocation);
}
}
}
public int loadBeanDefinitions(String location, Set<Resource> actualResources)
throws BeanDefinitionStoreException {
ResourceLoader resourceLoader = getResourceLoader();
if (resourceLoader instanceof ResourcePatternResolver) {
// Resource pattern matching available.
try {
//这里的location就是配置文件-applicationContext.xml,转成Resource对象
Resource[] resources=resourceLoader).getResources(location);
//获取resources对象的输入流 再转成JDK的InputSource对象,最后解析成Document
InputStream inputStream = resources.getInputStream();
InputSource inputSource = new InputSource(inputStream);
Document doc = doLoadDocument(inputSource, resource);
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"Could not resolve bean definition resource pattern [" + location + "]", ex);
}
}
}
[
[#text:],
[context:component-scan: null],
[#text:],
[bean: null],
[#text:],
[bean: null],
[#text:],
[bean: null],
[#text:],
[bean: null],
[#text:],
[#comment: 指定了表现层资源的前缀和后缀
viewClass:JstlView表示JSP模板页面需要使用JSTL标签库
prefix 和suffix:查找视图页面的前缀和后缀,比如传进来的逻辑视图名为hello,则该该
jsp视图页面应该存放在“WEB-INF/jsp/hello.jsp”],
[#text:],
[bean: null],
[#text: ]
]
//这里拿到的是Document对象的根节点,根节点信息参考上图
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;
//这里有两个分支。
//一个是处理默认的节点(import、alias、bean、beans)
//一个是处理自定义的节点(context:component-scan)
if (delegate.isDefaultNamespace(ele)) {
parseDefaultElement(ele, delegate);
}
else {
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
http\://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler http\://www.springframework.org/schema/jee=org.springframework.ejb.config.JeeNamespaceHandler http\://www.springframework.org/schema/lang=org.springframework.scripting.config.LangNamespaceHandler http\://www.springframework.org/schema/task=org.springframework.scheduling.config.TaskNamespaceHandler http\://www.springframework.org/schema/cache=org.springframework.cache.config.CacheNamespaceHandler
public NamespaceHandler resolve(String namespaceUri) {
//handlerMappings里有个方法loadAllProperties(),获取Spring所有的配置项
Map<String, Object> handlerMappings = 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 {
//以context:component-scan举例
//这里拿到的className就是org.springframework.context.config.ContextNamespaceHandler
//通过反射,实例化这个ContextNamespaceHandler,然后调用init方法
Class<?> handlerClass = ClassUtils.forName(className, this.classLoader);
NamespaceHandler namespaceHandler = BeanUtils.instantiateClass(handlerClass);
namespaceHandler.init();
handlerMappings.put(namespaceUri, namespaceHandler);
return namespaceHandler;
}
}
}
public void init() {
registerBeanDefinitionParser("annotation-config",
new AnnotationConfigBeanDefinitionParser());
registerBeanDefinitionParser("component-scan",
new ComponentScanBeanDefinitionParser());
}
public BeanDefinition parse(Element element, ParserContext parserContext) {
//获取包扫描路径,对应配置文件中的base-package="com.viewscenes.netsupervisor"
String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);
basePackage = parserContext.getReaderContext().getEnvironment().
resolvePlaceholders(basePackage);
//这里可能有多个包路径,分割成数组
String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
/**
* configureScanner 配置扫描器。
* scanner.doScan 扫描执行
* registerComponents 这里重点是对registerComponents的支持
*
* @return
*/
ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
registerComponents(parserContext.getReaderContext(), beanDefinitions, element);
return null;
}
protected void registerDefaultFilters() {
//这个就是配置的use-default-filters,如果配置了false。那么下面的
// Component、ManagedBean、Named注解都不会被扫描到
if (useDefaultFilters) {
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)),
false));
logger.debug("JSR-250 'javax.annotation.ManagedBean'
found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
}
}
}
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<BeanDefinitionHolder>();
for (String basePackage : basePackages) {
//findCandidateComponents方法扫描class文件,判断Component注解,转成BeanDefinition对象返回。
//值得注意的是,Component不止是@Component,还有
//@Controller、@Service、@Repository,因为在这三个注解上面还有个@Component。
//这就相当于它们都是Component的子注解。
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.
resolveScopeMetadata(candidate);
//设置属性,没有配置的都是默认值
candidate.setScope(scopeMetadata.getScopeName());
candidate.setxxx(scopeMetadata.getxxxName());
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
//registerBeanDefinition方法 注册BeanDefinition,等同于下面两句
//this.beanDefinitionMap.put(beanName, beanDefinition);
//this.beanDefinitionNames.add(beanName);
registerBeanDefinition(definitionHolder, this.registry);
}
}
return beanDefinitions;
}
[ Generic bean: class [com.viewscenes.netsupervisor.controller.IndexController]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\apache-tomcat-7.0.78\webapps\springmvc_dubbo_producer\WEB-INF\classes\com\viewscenes\netsupervisor\controller\IndexController.class], Generic bean: class [com.viewscenes.netsupervisor.controller.UserController]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\apache-tomcat-7.0.78\webapps\springmvc_dubbo_producer\WEB-INF\classes\com\viewscenes\netsupervisor\controller\UserController.class] ]
protected void registerComponents(XmlReaderContext readerContext,
Set<BeanDefinitionHolder> beanDefinitions, Element element) {
boolean annotationConfig = true;
if (element.hasAttribute(ANNOTATION_CONFIG_ATTRIBUTE)) {
annotationConfig = Boolean.valueOf(element.getAttribute(ANNOTATION_CONFIG_ATTRIBUTE));
}
if (annotationConfig) { //判断annotation-config属性的值
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(4);
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
}
}
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
//获取bean_id
String id = ele.getAttribute(ID_ATTRIBUTE);
String beanName = id;
AbstractBeanDefinition beanDefinition =
parseBeanDefinitionElement(ele, beanName, containingBean);
String[] aliasesArray = StringUtils.toStringArray(aliases);
//最后返回已经包含了beanName、class对象和一系列方法的BeanDefinition对象
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
}
public AbstractBeanDefinition parseBeanDefinitionElement(Element ele,
String beanName, BeanDefinition containingBean) {
String className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
try {
//根据className反射设置setBeanClass和setBeanClassName
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
//设置默认方法 setScope、setLazyInit、setAutowireMode...
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
//设置property属性 <bean><property name="id" value="1001"></property></bean>
parsePropertyElements(ele, bd);
return bd;
}
return null;
}
【关注微信公众号获取更多学习资料】