spring-context.xml 文件配置的简单介绍

xiaoxiao2021-02-28  60

0.头文件

<?xmlversion="1.0"encoding="UTF-8"?>

<beansxmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"

xmlns:tx="http://www.springframework.org/schema/tx"xmlns:task="http://www.springframework.org/schema/task"

xmlns:aop="http://www.springframework.org/schema/aop"

xsi:schemaLocation="

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-4.3.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-4.3.xsd

http://www.springframework.org/schema/tx 

http://www.springframework.org/schema/tx/spring-tx-4.3.xsd

http://www.springframework.org/schema/task

http://www.springframework.org/schema/task/spring-task-4.3.xsd

http://www.springframework.org/schema/aop   

       http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">

1.<context:property-placeholder location="classpath:system/*.properties" />

导入src目录下的system下的所有properties文件。

2.<context:annotation-config />

3.<tx:annotation-driven transaction-manager="transactionManager" />

注 : Controller可以使用@Transactional

在使用SpringMvc的时候,配置文件中我们经常看到 annotation-driven 这样的注解,其含义就是支持注解,一般根据前缀 tx、mvc 等也能很直白的理解出来分别的作用。<tx:annotation-driven/> 就是支持事务注解的(@Transactional) 、<mvc:annotation-driven> 就是支持mvc注解的,说白了就是使Controller中可以使用MVC的各种注解。

    首先,<tx:annotation-driven/>  会有一个属性来指定使用哪个事务管理器,如:<tx:annotation-driven transaction-manager="transactionManager" />然后事务管理器 transactionManager 会引用 dataSource (如果我们使用JPA或hibernate,也需要指定一个 entityManagerFactory ),dataSouce 肯定就是直接对数据库的了。

    这样逐层引用下去,所以我们使用@Transactionl 注解可以控制事务就通俗易懂了。另外要提一下的就是 spring 是使用 aop 通过 asm 操作java字节码的方式来实现对方法的前后事务管理的。

    说到这里,已经有了对 <tx:annotation-driven/> 的简单理解,那我们是否就可以在程序中所有被spring管理的类上都可以使用@Transactional注解了呢,在Service上可以使用@Transactional 注解这个是肯定的了,那总有些人也想弄明白能否在Controller 使用?答案显然是“不一定”的(与时间配置有关),下面做下解释:

在 spring-framework-reference.pdf 文档上有这样一段话:

<tx:annotation-driven/> only looks for @Transactional on beans in the same application context it is defined in. This means that, if you put <tx:annotation-driven/> in a WebApplicationContext for a DispatcherServlet, it only checks for @Transactional beans in your controllers, and not your services. 

意思就是:<tx:annoation-driven/>只会查找和它在相同的应用上下文件中定义的bean上面的@Transactional注解,如果你把它放在Dispatcher的应用上下文中,它只检查控制器(Controller)上的@Transactional注解,而不是你services上的@Transactional注解。

    所以,可以确定的是我们是可以在Controller上使用事务注解的,但是我们不推荐这样做,这里只是为了说明spring对<tx:annotation-driven/>的使用。

4.<task:executor id="taskExecutor" pool-size="1-20"

queue-capacity="30" keep-alive="60" />

5.<task:scheduler id="scheduler" pool-size="1" />

6.<task:annotation-driven executor="taskExecutor"

scheduler="scheduler" />

Spring3.0以后自主开发的定时任务工具,spring task,可以将它比作一个轻量级的Quartz,而且使用起来很简单,除spring相关的包外不需要额外的包,而且支持注解和配置文件两种  

Spring 实用注解来调度定时任务。 配置自动调度的包和定时开关

1.在需要加载spring的配置文件里spring.xml / applicationContext.xml 添加

[html]  view plain copy xmlns:task="http://www.springframework.org/schema/task"   xsi:schemaLocation="   http://www.springframework.org/schema/task           http://www.springframework.org/schema/task/spring-task-3.0.xsd

 <task:executor id="taskExecutor" pool-size="1-20"

queue-capacity="30" keep-alive="60" />

注 :整合TaskExecutor线程池的配置

核心线程数:pool-size ;

队列最大长度:queue-capacity; 线程池维护线程所允许的空闲时间,默认为60s:keep-alive

在实现层Impl声明并注入:

@Resource(name = "taskExecutor") private TaskExecutor taskExecutor;

在方法里调用:

try { taskExecutor.execute(new Runnable() { public void run() { //这里编写处理业务代码 } }); } catch (Exception e) { e.printStackTrace(); }

配置调度和注解调度

[html]  view plain copy <!-- 配置调度 需要在类名前添加 @Service -->       <!--             <task:scheduled-tasks>               <task:scheduled ref="demoTask" method="myTestWork" cron="0/10 * * * * ?"/>           </task:scheduled-tasks>       -->       <!-- 不通过配置调度,需要在类名前 @Component/@Service,在方法名 前添加@Scheduled(cron="0/5 * * * * ? ")-->  

在web.xml配置里添加启动时要扫描的配置文件和监听

[html]  view plain copy <context-param>      <param-name>contextConfigLocation</param-name>      <param-value>/WEB-INF/applicationContext*.xml</param-value>    </context-param>    <listener>      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    </listener>   添加调度的包

类测试

[java]  view plain copy @Service   public class demo {       @Scheduled(cron="0/5 * * * * ? ")       public void myTestWork(){              System.out.println("ssss");       }    }

7.<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">

<property name="url" value="${db.url}" />

<property name="driverClassName" value="${db.driver}" />

<property name="username" value="${db.username}" />

<property name="password" value="${db.password}" />

<property name="maxTotal" value="50" />

<property name="maxIdle" value="50" />

<property name="minIdle" value="5" />

<property name="initialSize" value="5" />

<property name="maxWaitMillis" value="-1" />

</bean>

配置数据源dataSource

此外还需要src文件夹里新建一个jdbc.properties文件,里面的内容为如下:

db.driver=com.mysql.jdbc.Driver db.url=jdbc:mysql://172.20.13.55:3306/study?useUnicode=true&characterEncoding=utf8 db.username=study db.password=******

<!-- 连接池的最大值,同一时间可以从池分配的最多连接数量,0时无限制 --> <property name="maxTotal" value="${maxActive}" /> <!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 ,0时无限制--> <property name="maxIdle" value="${maxIdle}" /> <!-- 最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请 --> <property name="minIdle" value="${minIdle}" /> <!-- 连接初始值,连接池启动时创建的连接数量的初始值 --> <property name="initialSize" value="${initialSize}" /> <!-- 获取数据库连接的最长等待时间,-1表示无限期等待 --> <property name="maxWaitMillis" value="-1" />

8.

<bean id="sessionFactory"

class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">

<property name="dataSource" ref="dataSource" />

<property name="packagesToScan" value="jp.iesolutions.study.models" />

<property name="annotatedPackages">

<list>

<value>jp.iesolutions.study.models</value>

</list>

</property>

<property name="hibernateProperties">

<value>

hibernate.dialect=org.hibernate.dialect.DB2Dialect

hibernate.show_sql=true

hibernate.jdbc.batch_size=20

hibernate.autoReconnect=true

</value>

</property>

</bean>

<!-- 定义HibernateSessionFactory -->

<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">

<!-- 依赖注入数据源,正是上文定义的dataSource -->

<property name="dataSource" ref="dataSource" />

<!-- 实现实体类的扫描例如<property name="" value="com.xxx.entity" />会解析成"classpath*:com/xxx/entity**/*.class"

这个路径可以找出com/xxx/entity根目录下的类文件 -->

<property name="packagesToScan" value="jp.iesolutions.study.models" />

<!-- 定义HibernateSessionFactory属性 -->

<property name="hibernateProperties">

<!-- 指定Hibernate的连接方言 -->

hibernate.dialect=org.hibernate.dialect.DB2Dialect

<!-- 是否显示Sql语句 -->

hibernate.show_sql=true

<!--Batch Size是设定对数据库进行批量删除,批量更新和批量插入的时候的批次大小,有点相当于设置Buffer缓冲区大小的意思。Batch Size越大,批量操作的向数据库发送sql的次数越少,速度就越快。

-->

hibernate.jdbc.batch_size=20

<!-- Hibernate连接数据库超时设置-->

hibernate.autoReconnect=true

9. <beanid="transactionManager"

class="org.springframework.orm.hibernate5.HibernateTransactionManager">

<property name="sessionFactory" ref="sessionFactory" />

</bean>

定义了一个事务管理器transactionManager

10.

<beanid="transactionProxy"

class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"

abstract="true">

<property name="transactionManager" ref="transactionManager"></property>

<property name="transactionAttributes">

<props>

<prop key="add*">PROPAGATION_REQUIRED,-Exception</prop>

<prop key="modify*">PROPAGATION_REQUIRED,-myException</prop>

<prop key="del*">PROPAGATION_REQUIRED</prop>

<prop key="*">PROPAGATION_REQUIRED</prop>

</props>

</property>

</bean>

配置了事务代理

<!-- 为事务代理工厂Bean注入事务管理器 -->

<propertyname="transactionManager"ref="transactionManager"></property>

<!-- 指定事务属性 -->

PROPAGATION_MANDATORY要求调用该方法的线程必须处于事务环境中,否则抛出异常

PROPAGATION_NESTED:如果执行该方法的线程已处于事务环境下,依然启动新的事务,方法在嵌套的事务里执行。如果执行方法的线程为处于事务中,也启动新的事务,然后执行该方法,此时与PROPAGATION_REQUIRED相同

PROPAGATION_NEVER:不允许调用该方法的线程处于事务环境下,如果调用该方法的线程处于事务环境下,则抛出异常

PROPAGATION_NOT_SUPPORTED:如果调用该方法的线程处在事务中,则暂停当前事务,然后执行该方法

PROPAGATION_REQUIRED:要求在事务环境中执行该方法,如果当前执行的线程已处于事务中,则直接调用;如果当前执行线程不处于事务中,则启动新的事务后执行该方法

PROPAGATION_REQUIRES_NEW:要求在事务环境中执行该方法,如果当前执行的线程已处于事务中,则暂停当前事务,启动新事务后执行该方法;如果当前执行线程不处于事务中,则启动新的事务后执行该方法

PROPAGATION_SUPPORTS:如果当前执行线程处于事务中,则使用当前事务;不过不在事务中,则不使用事务

转载请注明原文地址: https://www.6miu.com/read-48485.html

最新回复(0)