恳请spring配置文件逐条详解,详见问题补充。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了恳请spring配置文件逐条详解,详见问题补充。相关的知识,希望对你有一定的参考价值。

比如第二个bean“transactionManager”,看名字就知道是事务控制相关的配置,但是它是如何实现的?不一定要说出很底层的原理,但还是希望能讲出一些哪怕是使用层面的道理,先谢了。

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath*:com/aspire/nm/sqsjb/umi/mapper/**/*.xml"/>
<property name="typeAliasesPackage" value="com.aspire.nm.sqsjb.umi.domain"/>
</bean>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

<!-- enable transaction demarcation with annotations -->
<tx:annotation-driven transaction-manager="transactionManager"/>

<!-- enable mapper scanning -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.aspire.nm.sqsjb.umi.mapper"/>
</bean>

<!-- enable component scanning (beware that this does not enable mapper scanning!) -->
<context:component-scan base-package="com.aspire.nm.sqsjb.umi.handler"/>
<context:component-scan base-package="com.aspire.nm.sqsjb.umi.service"/>
知道了这个bean是做什么的了,是因为引入了mybatis-spring.jar。这个bean就是用于创建sqlSessionFactory的。

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
</bean>

逐条解释肯定解释不完,就跟你讲一下事务管理的相关理解吧。


下面是Spring较早时期的一个配置,能体现出一点底层的东西。

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="com.mysql.jdbc.Driver" />
    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/" />
    <property name="user" value="root" />
    <property name="password" value="fuhaiwei" />
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="mappingResources" value="com/fuhaiwei/domain/domain.xml" />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
        </props>
    </property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager" >
    <property name="dataSource" ref="dataSource" />
</bean>

//看这个,这个是关键,事务管理是靠AOP实现的,下面是一个拦截器。
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
    <property name="transactionManager" ref="transactionManager" />
    <property name="transactionAttributes">
        //指定事务传播属性,例如getUser给予只读事务
        <props>
            <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
            <prop key="add*">PROPAGATION_REQUIRED</prop>
            <prop key="update*">PROPAGATION_REQUIRED</prop>
            <prop key="update*">PROPAGATION_REQUIRED</prop>
        </props>
    </property>
</bean>

//这个也是关键,指定那些Bean会启动上面的拦截器。
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
    <property name="interceptorNames" value="transactionInterceptor" />
    //指定所有Service结尾的Bean会启用事务管理。
    <property name="beanNames" value="*Service" />
</bean>

//现在使用的<tx:annotation-driven transaction-manager="transactionManager"/>
//直接替代了上述两条配置。

从上面的配置可以看出,Spring的事务管理要发挥作用有一些条件。

一:这个类要由Spring来管理,也就是说配置成一个Bean,并且程序中实际使用的必须是由容器注入的。(因为事务管理的实现原理是AOP代理,我们实际使用的UserService对象将是一个代理对象)


二:我们应该告诉Spring,我们想在那些类或者说Bean上启用事务。


三:我们应该告诉Spring,我们想在那些方法上启用事务。(因为AOP代理一般是使用JDK动态代理机制,而JDK想要代理的方法,必须实现于一个接口,所以我们经常发现由Spring管理的项目,其Service和Dao常常都有接口类)


四:我们在Dao中,获取Session时,应该用getCurrentSession()方法,而不是openSession()方法,因为openSession()方法会打开一个全新的Session,且不与线程关联。事务管理器到时候无法获取这个Session也就无法管理事务。而如果使用getCurrentSession()方法,这个方法获取的事务是与线程关联的,到时候事务管理器就可以打开事务,提交事务,或者回滚事务。


五:这是的transactionInterceptor一个片段

 public Object invoke(final MethodInvocation invocation) throws Throwable 
     //如有必要打开事务。
    TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
    Object retVal = null;
    try 
        //运行被代理类的实际方法,也就是我们的Service类的某个方法
        retVal = invocation.proceed();
    
    catch (Throwable ex) 
        //如果抛出异常就回滚事务(默认配置情况下)
        completeTransactionAfterThrowing(txInfo, ex);
        throw ex;
    
    finally 
        cleanupTransactionInfo(txInfo);
    
    //如果没有异常就提交事务
    commitTransactionAfterReturning(txInfo);
    return retVal;

最后总结,这里面设计到很多个知识点,如什么是AOP,SpringAOP实现的方法是什么,什么是JDK动态代理,什么是Spring自动代理工厂,很多很多,不知道你掌握的情况,所以有问题请追问吧。

参考技术A http://wenku.baidu.com/view/8391531da76e58fafab00369.html
http://wenku.baidu.com/view/45dbc60e7cd184254b3535c9.html
配置参考以上内容;
底层实现需要看spring源码。可以下载一个研究下,非三言两语说清楚的啊

spring的xml配置文件的xml文件头详解

参考技术A

在spring的xml配置文件中,在头部会出现如下的东西

这些奇怪的xmlns和很长的url的作用是什么呢?

首先,介绍一下 xmlns 的作用,如下所示,一个 xml 文档中如果包含如下两种定义不同, 但是名称相同的元素, xml 解析器是无法解析的, 因为它不能确定当你调用document.getElementsByTagName("book") 时应该返回哪个元素。

这时候可以通过在名称增加前缀解决这个问题

由此,引入一个概念 命名空间 ,通过增加前缀表示不同的那是不同命名空间下的table,从而解决了矛盾,但是不同的人都有自己创建的不同的命名空间来描述同样的东西,不利于xml文件信息的解析,比如说,同样都是水果,可以从颜色和香味不同角度来定义成如下两种形式:

为此,w3c(万维网联盟)对于一些类型,定义了对应的命名空间和这些类型的标准,xml解释器碰到这些类型的时候就会通过这些标准去解析这类型的标签,为了确保命名空间的唯一,所以不同的命名空间的通常使用URL作为被识别的id,如下例子:

这句话的作用是当前引入了一个叫做xsi的命名空间,xsi可以在接下来要使用该命名空间时所使用的,如下:

而 http://www.w3.org/2001/XMLSchema-instance 这个很长的字符串,则是xsi这个名称空间被xml解释器内部所识别的时候所真正使用的id,但也本身只是被当做一个字符串名字去处理,xml解释器根据这个id去获取它对应的标准,从而知道这个命名空间定义有什么样的标签(xml解释器自带有一些通用的命名空间的标准),这个字符串虽然看起来是URL,但是和对应的网页上的信息没有关系,只是用来提供命名空间 唯一性 的作用,网址有时可以被打开,上面会有关于该命名空间的信息。

所以,spring配置文件中这三句话分别表示,引入了三个命名空间。
其中第一个xmlns后面没有空间名的,表示引入了一个默认的名称空间,下文中不使用命名空间前缀的都默认使用这个命名空间,这个默认的命名空间,其真正的id是 " http://www.springframework.org/schema/beans "
引入的第二个命名空间叫做xsi,其真正的id是 " http://www.w3.org/2001/XMLSchema-instance "
引入的第三个命名空间叫做context,其真正的id是 " http://www.springframework.org/schema/context "

在最后可以看到xsi:schemaLocation,这句话的意思表示使用命名空间xsi下的schemaLocatioin,设置了它对应的值为后面很多很多的URL,schemaLocation中存储的值每两个为一组, 第一个代表命名空间,第二个代表该命名空间的标准的文件位置 ,如下所示,这句话就是说明命名空间 http://www.springframework.org/schema/beans 的标准文件是 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd *

因为xml解释器不一定含有所有命名空间的标准,通过这样设置就可以告诉xml解释器不同命名空间的对应的标准是什么了,而这也是xsi这个命名空间的作用,要用到其schemaLocation。

最后,对应一般的xml解释器的工作流程中,xml解释器识别到有 “ http://www.w3.org/2001/XMLSchema-instance " 这个通用的名称空间后,明白知道要引入一些不同命名空间,就会从其schemaLocation中获取不同命名空间和其对应的标准。

以上是关于恳请spring配置文件逐条详解,详见问题补充。的主要内容,如果未能解决你的问题,请参考以下文章

spring配置文件详解

python 插入文本 详见问题补充

Spring Boot属性配置文件详解

Spring和MyBatis配置补充

Spring Task定时任务的配置和使用详解

Spring配置补充