声明事务 与 注解事务
用@Transaction 注解事务, 与aop 的expression 正则配置方法的事务是冲突的;
@Transaction 在类中配置了全局事务
@Transaction(propagation=Propagation.SUPPORT)
注释配置相对于xml 配置与很多的优势,它可以充分利用java的反射机制获取类结构信息,这些信息可以有效减少配置工作;
@Autowired注释
@Autowired 注释,它可以对类成员变量,方法及构造函数进行标注,完成自动装配的工作;
@Autowired(required = false) 告诉spring,在找不到Bean时候也不报错;
@Qualifier("bean")
当@Autowired和@Qualifier 结合使用的时候.自动注入的策略就从byType 转变成了 byName
@Resource 与 @Autowired + @Qualifier
使用@Component
@Repository 的基础上增加了功能类似的额外三个注解:
@Component @Service @Constroller 它们分别用于软件系统的不同层次:
?@Component 是一个泛化的概念,仅仅表示一个组件 (Bean),可以作用在任何层次
?@Service 通常作用在业务层,但是目前该功能与 @Component 相同
?@Constroller 通常作用在控制层,但是目前该功能与 @Component 相同
.@scope
Spring 2.5 中除了提供 @Component 注释外,还定义了几个拥有特殊语义的注释,它们分别是:
@Repository @Service 和@Controller.在目前的 Spring 版本中,这 3 个注释和@Component 是等效的,
但是从注释类的命名上,很容易看出这 3 个注释分别和持久层,业务层和控制层(Web 层)相对应,虽
然目前这3 个注释和@Component 相比没有什么新意,但 Spring 将在以后的版本中为它们添加特殊
的功能.所以,如果 Web 应用程序采用了经典的三层分层结构的话,最好在持久层、业务层和控制
层分别采用@Repository @Service 和 @Controller 对分层中的类进行注释,而用@Component 对那些
比较中立的类进行注释
注释配置和xml 配置的适用场合:
有了IOC 注释,也不可以完全摒除原来XML 配置的方式
1) 注释配置不一定在先天上优秀于xml配置,如果bean的依赖关系是固定的,如:service适用了哪几个dao类
这种配置信息不会在部署时候发生调整,那么注释配置优秀于xml 配置,反之如果这种依赖关系会在部署
时发生调整,XML 配置显然又优于注释配置,因为注释是对 Java 源代码的调整,您需要重新改写源代
码并重新编译才可以实施调整
2) ?如果 Bean 不是自己编写的类(如 JdbcTemplate,SessionFactoryBean 等)注释配置将无法实施,此时 XML
配置是唯一可用的方式
3) ?注释配置往往是类级别的,而 XML 配置则可以表现得更加灵活,比如相比于 @Transaction 事务注释,使用
aop/tx 命名空间的事务配置更加灵活和简单
所以在实现应用中,我们往往需要同时使用注释配置和 XML 配置,对于类级别且不会发生变动的配置可以优
先考虑注释配置,而对于那些第三方类以及容易发生调整的配置则应优先考虑使用 XML 配置,Spring 会在具
体实施 Bean 创建和 Bean 注入之前将这两种配置方式的元信息融合在一起
Spring 数据源配置:
spring 在第三方依赖包中包含了两个数据源的实现包,其一是Apache的DBCP,其二是C3P0,可以在spring 配置文件
中利用这两者中任何一个配置数据源::
DBCP 类包位于:>/lib/jakarta-commons/commons-dbcp.jar,DBCP 是一个依赖于Jakarta commons-pool对象池机制的
数据库连接池,所以在类下还必须包括>/lib/jakarta- commons/commons-pool.jar
例子: 使用DBCP配置mysql 数据源::
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destory-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3360/sampledb"/>
<property name="username" value="root" />
<property name="password" value="1234" />
</bean>
BasicDataSource 提供了close()方法关闭数据源, 所以必须设定destory-method="close" 属性,以便spring容器关闭时候,
数据源能够正常关闭,除了以上必须的数据源属性以外,还有一些常用的属性::
defaultAutoCommit: 设置从数据源中返回的连接是否采用自动提交机制,默认为true::
defaultReadOnly : 设置数据源是否仅能执行只读操作, 默认值为false::
maxIdle: 最大等待连接中的数量,设置为0 时候,表示没有限制::
maxWait : 最大等待秒数,单位为毫秒,超过时间会报错误信息::
validationQuery:用于验证连接是否成功的查询sql语句,sql语句必须至少返回一行数据,如你可以简单的设置为
select count(*) from user;
C3P0是一个开放源代码的JDBC 数据源实现项目,它在lib目录中与Hibernate 一起发布,实现了JDBC3和JDBC2 扩展规范说明
的Connect 和statement 池,c3p0位于: >/lib/c3p0/c3p0-0.9.0.4.jar
<bean id="dataSource" class="com.mchage.v2.c3p0.ComboPooledDataSource" destory-method="close">
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver" />
<property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:ora9i"/>
<property name="user" value="admin" />
<property name="password" value="1234" />
</bean>
ComboPooledDataSource和BasicDataSource一样提供了一个用于关闭数据源的close()方法,这样我们就可以保证Spring容器
关闭时数据源能够成功释放
C3P0拥有比DBCP更丰富的配置属性,通过这些属性,可以对数据源进行各种有效的控制:
acquireIncrement:当连接池中的连接用完时,C3P0一次性创建新连接的数目
acquireRetryAttempts:定义在从数据库获取新连接失败后重复尝试获取的次数,默认为30
acquireRetryDelay:两次连接中间隔时间,单位毫秒,默认为1000
autoCommitOnClose:连接关闭时默认将所有未提交的操作回滚,默认为false
其它的属性找文档来看::
读配置文件的方式引用属性:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="/WEB-INF/jdbc.properties" />
</bean>
<bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" >
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" vlaue="${jdbc.username}" />
<property name="password" value="${dbc.password}" />
</bean>
在jdbc.properties属性文件中定义属性值:
jdbc.driverClassName= com.mysql.jdbc.Driver
jdbc.url= jdbc:mysql://localhost:3309/sampledb
jdbc.username=root
jdbc.password=1234
提示经常有开发者在${xxx}的前后不小心键入一些空格,这些空格字符将和变量合并后作为属性的值,如
<property name="username" value=" ${jdbc.username} "></property> 的属性配置项,在前后都有空格,被解
析后,username的值为" 1234 "这将造成最终的错误,因此需要特别小心
获取JNDI数据源
如果应用配置在高性能的应用服务器(如WebLogic或Websphere等)上,我们可能更希望使用应用服务器本身
提供的数据源,应用服务器的数据源 使用JNDI开放调用者使用,Spring为此专门提供引用JNDI资源的
JndiObjectFactoryBean类,下面是一个简单的配置:
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<propery name="jndiName" value="java:comp/env/jdbc/bbt" />
</bean>
03.</bean>
通过jndiName指定引用的JNDI数据源名称。
Spring 2.0为获取J2EE资源提供了一个jee命名空间,通过jee命名空间,可以有效地简化J2EE资源的引用
下面是使用jee命名空间引用JNDI数据源的配置:
01.<beans xmlns=http://www.springframework.org/schema/beans
02.xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
03.xmlns:jee=http://www.springframework.org/schema/jee
04.xsi:schemaLocation="http://www.springframework.org/schema/beans
05.http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
06.http://www.springframework.org/schema/jee
07.http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">
08.<jee:jndi-lookup id="dataSource" jndi-name=" java:comp/env/jdbc/bbt"/>
09.</beans>
09.</beans>
Spring的数据源实现类
Spring本身也提供了一个简单的数据源实现类DriverManagerDataSource ,它位于org.springframework.jdbc.datasource包中
这个类实现了javax.sql.DataSource接口,但它并没有提供池化连接的机制,每次调用getConnection()获取新连接时,只是
简单地创建一个新的连接,因此,这个数据源类比较适合在单元测试 或简单的独立应用中使用,因为它不需要额外的依赖类。
看一下DriverManagerDataSource的简单使用:当然,也可以通过配置的方式直接使用DriverManagerDataSource。
01.DriverManagerDataSource ds = new DriverManagerDataSource ();
02.ds.setDriverClassName("com.mysql.jdbc.Driver");
03.ds.setUrl("jdbc:mysql://localhost:3309/sampledb");
04.ds.setUsername("root");
05.ds.setPassword("1234");
06.Connection actualCon = ds.getConnection();
java 代码
小结
不管采用何种持久化技术,都需要定义数据源,Spring附带了两个数据源的实现类包,你可以自行选择进行定义,在实际部署时,
可能会直接采用应用服务器本身提供的数据源,这时,则可以通过JndiObjectFactoryBean或jee命名空间引用JNDI中的数据源
DBCP与C3PO配置的区别:
C3PO :DBCP:
xml 代码
01.<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
02. <property name="driverClass">
03. <value>oracle.jdbc.driver.OracleDriver</value>
04. </property>
05. <property name="jdbcUrl">
06. <value>jdbc:oracle:thin:@10.10.10.6:1521:DataBaseName</value>
07. </property>
08. <property name="user">
09. <value>testAdmin</value>
10. </property>
11. <property name="password">
12. <value>123456</value>
13. </property>
14.</bean>
xml 代码
01.<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
02. <property name="driverClassName">
03. <value>oracle.jdbc.driver.OracleDriver</value>
04. </property>
05. <property name="url">
06. <value>jdbc:oracle:thin:@10.10.10.6:1521:DataBaseName</value>
07. </property>
08. <property name="username">
09. <value>testAdmin</value>
10. </property>
11. <property name="password">
12. <value>123456</value>
13. </property>
14.</bean>
*************************************************************************************
如果使用注解事务, 利用使用JDBC事务的时候,要提供事务管理:
针对哪个数据源使用事务管理:
<!-- 数据库连接池 -->
<bean id="dataSourceNew" class="com.mchange.v2.c3p0.ComboPooledDataSource"
p:driverClass="oracle.jdbc.OracleDriver"
p:jdbcUrl="jdbc:oracle:thin:@localhost:1521:ORACLE"
p:user="movers" p:password="xzsp12" />
<!-- JDBC的事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSourceNew" />
<!-- 使用声明式事务管理 -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
**************************************************************************************
我在交管局做的数据同步项目是的,配置文件:
<!-- 扫描包结构找到使用了annotation的类 -->
<context:component-scan base-package="com.whclx" />
<!-- 使用声明式事务管理 -->
<!--<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/> -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
<!-- 数据库连接池 -->
<bean id="dataSourceOld" class="com.mchange.v2.c3p0.ComboPooledDataSource"
p:driverClass="oracle.jdbc.OracleDriver"
p:jdbcUrl="jdbc:oracle:thin:@localhost:1521:ORACLE"
p:user="xzsp" p:password="xzsp12" />
<!-- 数据库连接池 -->
<bean id="dataSourceNew" class="com.mchange.v2.c3p0.ComboPooledDataSource"
p:driverClass="oracle.jdbc.OracleDriver"
p:jdbcUrl="jdbc:oracle:thin:@localhost:1521:ORACLE"
p:user="movers" p:password="xzsp12" />
<!-- 数据库连接池 -->
<bean id="dataSourceParam" class="com.mchange.v2.c3p0.ComboPooledDataSource"
p:driverClass="oracle.jdbc.OracleDriver"
p:jdbcUrl="jdbc:oracle:thin:@localhost:1521:ORACLE"
p:user="sxmc" p:password="sxmc12" />
<!-- JDBC的事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSourceNew" />
<bean id="uploadService" class="com.whclx.service.UploadService">
<property name="dataSource" ref="dataSourceOld" />
</bean>
<bean id="filterService" class="com.whclx.service.FilterService">
<property name="dataSource" ref="dataSourceNew"/>
</bean>
<bean id="deptidService" class="com.whclx.service.GetDeptService">
<property name="dataSource" ref="dataSourceParam"/>
</bean>
<bean id="phoneService" class="com.whclx.service.PhoneService">
<property name="dataSource" ref="dataSourceOld"/>
</bean>
<bean id="commitService" class="com.whclx.service.CommitService">
<property name="dataSource" ref="dataSourceNew"/>
</bean>
<bean id="parameterService" class="com.whclx.service.ParameterService"/>
<!-- quartz 配置 -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="myTrigger"/>
</list>
</property>
<property name="autoStartup" value="true"/>
</bean>
<!-- trigger 配置 -->
<bean id="myTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="myJobDetail"/>
<property name="cronExpression" value="0 0 12 * * ?"/>
</bean>
<!-- JobDetail 配置 -->
<bean id="myJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="taskJob"/>
<property name="targetMethod" value="execute"/>
<property name="concurrent" value="false"/>
</bean>
<!-- 业务类的配置 -->
<bean id="taskJob" class="com.whclx.utils.TaskExe"/>
</beans>
*************************************************************************************
web.xml ::
<!-- 加载 spring 核心 配置文件-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:application-context.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
spring注解
最新推荐文章于 2022-07-23 10:40:51 发布