Spring Bean XML 配置解析

Spring Bean XML 配置解析

配置示例代码

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 启动注解驱动的spring MVC功能,注册请求url和注解POJO类方法的映射-->
    <mvc:annotation-driven/>

    <context:component-scan base-package="com.zxguan.template"/>
    <!--静态文件-->
    <mvc:default-servlet-handler/>
    <!-- 对模型视图名称的解析,在请求时模型视图名称添加前后缀 -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="view/"/>      <!-- 前缀 -->
        <property name="suffix" value=".jsp"/>   <!-- 后缀 -->
    </bean>
</beans>

原理解析

1. ResourceLoader 资源加载

ResourcePatternResolver(PathMatchingResourcePatternResolver): 资源表达式配置处理,负责资源加载解析为 Resource

2. DocumentLoader XML Document 加载器

DefaultDocumentLoader:XML Document 默认加载实现,解析为 Document

解析结构(对应配置示例代码)

Document(配置文件)
	- Element(<beans></beans>)
		- Node(<bean></bean>)
		- Node(<import/>)
		- Node(<alias/>)
		- Node(<beans/>)
		- Node(<mvc:annotation-driven/>)
		- Node(<context:component-scan/>)
		- Node(<mvc:default-servlet-handler/>)
		- ......
		- ......
		- ......
3. BeanDefinitionReader Bean 定义阅读器

XmlBeanDefinitionReader:XML 文件 Bean 定义阅读器,解析成 Document,且解析后每个节点都会有其对应的命名空间名称属性

4. BeanDefinitionDocumentReader Bean 定义Document 阅读器

DefaultBeanDefinitionDocumentReader:默认的 BeanDefinitionDocumentReader 实现,可能后续出现其他 Document 阅读者

5. BeanDefinitionParserDelegate Bean 定义解析委托类

BeanDefinitionParserDelegate:负责具体的 XML 配置解析,即 Document 中内容的解析。此处定义了 Spring XML Bean 配置的所有配置项属性及解析,

包含以下几类:

<import resource="datasource.xml"/>

<alias name="resourceHolder" alias="resourceHolder1"/>

<bean id="testController" class="com.zxguan.template.controller.TestController"/>

<beans></beans>

Spring 关于命名空间的规定:

Spring 命名空间类别
http://www.springframework.org/schema/beans默认
http://www.springframework.org/schema/beans 之外的命名空间,
如:http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/mvc 等等
自定义

判断节点中命名空间是 默认 还是 自定义 。如果是自定义则根据命名空间查找 NamespaceHandler 对应的实现类,进而解析配置信息。

	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);
		}
	}
6. NamespaceHandlerResolver 命名空间处理器的处理者

默认:DefaultNamespaceHandlerResolver:负责 NamespaceHandler 的选择

debug 调试时, IDEA 会开启另一个线程调用 DefaultNamespaceHandlerResolver 的 toString 方法,进而初

始化 handlerMappings,此时会发现打断点无法进入到初始化程序中,就是这个原因。

对于重写了 toString 方法的类,在用 Debug 调试时 IDEA 会另起一个线程调用 toString 方法,toString 的调用过程,IDEA 无法监听到

7. NamespaceHandler 命名空间处理器

NamespaceHandlerSupport:NamespaceHandler 的抽象实现,负责除 BeanDefinitionParserDelegate 中默认解析不能处理的标签的解析处理。其子类负责注册命名空间名与对应解析类映射,如:

public class MvcNamespaceHandler extends NamespaceHandlerSupport {

	@Override
	public void init() {
		registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
		registerBeanDefinitionParser("default-servlet-handler", new DefaultServletHandlerBeanDefinitionParser());
		registerBeanDefinitionParser("interceptors", new InterceptorsBeanDefinitionParser());
		registerBeanDefinitionParser("resources", new ResourcesBeanDefinitionParser());
		registerBeanDefinitionParser("view-controller", new ViewControllerBeanDefinitionParser());
		registerBeanDefinitionParser("redirect-view-controller", new ViewControllerBeanDefinitionParser());
		registerBeanDefinitionParser("status-controller", new ViewControllerBeanDefinitionParser());
		registerBeanDefinitionParser("view-resolvers", new ViewResolversBeanDefinitionParser());
		registerBeanDefinitionParser("tiles-configurer", new TilesConfigurerBeanDefinitionParser());
		registerBeanDefinitionParser("freemarker-configurer", new FreeMarkerConfigurerBeanDefinitionParser());
		registerBeanDefinitionParser("groovy-configurer", new GroovyMarkupConfigurerBeanDefinitionParser());
		registerBeanDefinitionParser("script-template-configurer", new ScriptTemplateConfigurerBeanDefinitionParser());
		registerBeanDefinitionParser("cors", new CorsBeanDefinitionParser());
	}

}

SecurityNamespaceHandler:负责 spring-security 配置解析,位于 spring-security-config 包中,示例配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:security="http://www.springframework.org/schema/security"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">

    <security:http pattern="/statics/**" security="none"/>
    <security:http  auto-config="true" use-expressions="true">
        <security:intercept-url pattern="/login.do" access="isAnonymous()"/>
        <security:intercept-url pattern="/register.do" access="isAnonymous()"/>
        <security:intercept-url pattern="/registerusers.do" access="isAnonymous()"/>
        <security:intercept-url pattern="/useradd.do" access="isAnonymous()"/>
        <security:intercept-url pattern="/admins/**" access="hasRole('ROLE_ADMIN')"/>
        <security:intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>
        <security:csrf disabled="false" token-repository-ref="cookieCsrfTokenRepository" />
        <security:form-login login-page="/login.do" login-processing-url="/login"  username-parameter="username" password-parameter="password" authentication-failure-url="/login.do?error=true" />
        <security:logout invalidate-session="true" logout-url="/logout" logout-success-url="/login.do"/>
        <security:http-basic />
        <security:remember-me data-source-ref="dataSource" key="youkey" remember-me-parameter="remember-me"/>
        <security:session-management>
            <security:concurrency-control  />
        </security:session-management>
    </security:http>
    
    <security:authentication-manager>
        <!--静态添加的用户登录信息-->
        <!--<security:authentication-provider>
            <security:user-service>
                <security:user name="admin" password="admin123" authorities="ROLE_USER,ROLE_ADMIN"/>
                <security:user name="user" password="user123" authorities="ROLE_USER"/>
            </security:user-service>
        </security:authentication-provider>-->
        <security:authentication-provider>
            <security:password-encoder ref="bCryptPasswordEncoder"/>
            <security:jdbc-user-service id="userDetailsService" data-source-ref="dataSource"
                                        users-by-username-query="SELECT username,password,enabled FROM users WHERE username=?"
                                        authorities-by-username-query="SELECT u.username as username,r.rolename as authority FROM users u join userrole ur on u.userid=ur.userid join roles r on r.roleid=ur.roleid WHERE u.username=?"/>
        </security:authentication-provider>
    </security:authentication-manager>

    <bean id="bCryptPasswordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
    <bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
        <property name="hideUserNotFoundExceptions" value="false"/>
        <property name="userDetailsService" ref="userDetailsService"/>
        <property name="passwordEncoder" ref="bCryptPasswordEncoder"/>
    </bean>
    <bean id="cookieCsrfTokenRepository" class="org.springframework.security.web.csrf.CookieCsrfTokenRepository">
        <property name="cookieHttpOnly" value="false"/>
    </bean>
</beans>
8. BeanDefinitionParser Bean 定义解析器

如:DefaultServletHandlerBeanDefinitionParser:负责 XML 中 <mvc:default-servlet-handler/> 的解析

9. ParserContext 解析上下文

负责提供一些解析所需用到的上下参数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值