SSM Chapter 08 Spring 配置补充 笔记
本章目标:
- 掌握更多配置数据源的方法
- 理解Bean的作用域
- 会使用Spring自动装配
- 会拆分Spring配置文件
1 . 灵活配置 DataSource
实现Spring 和 MyBatis 集成的过程中,我们学习了在Spring中配置数据源的方法.实际开发中,数据源还有很多灵活的配置方式可以选择.
1.1 使用属性文件配置数据源
Spring 提供的 PropertyPlaceholderConfigurer 类可以加载属性文件.在Spring 配置文件中 可以采用${…}的方式引用属性文件中的键值对.读取属性文件配置DataSource的方法如下:
在Spring的配置文件中,代码修改如下:
<!--引入properties文件-->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:database.properties"/>
</bean>
<!--配置数据源-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</bean>
<!--省略配置sqlSessionFactoryBean-->
<!--省略配置DAO 以及 业务Bean配置-->
<!--省略事务管理配置-->
database.properties 属性文件内容如下:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/foo?useUnicode=true&characterEncoding=utf-8
username=root
password=root
Spring 对于PropertyPlaceholderConfigurer 这个类 还提供了一个标签, 来简化它,代码如下:
<!--引入properties文件-->
<context:property-placeholder location="database.properties"/>
<!--配置数据源-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--省略配置sqlSessionFactoryBean-->
<!--省略配置DAO 以及 业务Bean配置-->
<!--省略事务管理配置-->
database.properties 属性内容如下:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/foo?useUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=root
注意:
- 使用
<context:property-placeholder>
标签时,按照上面的代码进行配置,这是Spring 4.0.4 之后的版本官方文档所规定的。建议在database.properties属性文件的键之前加入jdbc.
,以确保使用关键字时,不会抛出异常保证 。 - 经常有开发者 在 书写
${...}
的前后不小心输入了一些空格,这些空格字符将和变量合并后作为属性的值,被Spring所解析,最终引发异常。因此书写配置文件的代码时,要格外认真。
> 扩展使用<util-properties/>
元素
使用<util-properties/>
指定database.properties
配置文件所在的位置 , 代码如下:
<!--引入properties文件-->
<util:properties id="db" location="classpath:database.properties"/>
<!--配置数据源-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="#{db.driver}"/>
<property name="url" value="#{db.url}"/>
<property name="username" value="#{db.username}"/>
<property name="password" value="#{db.password}"/>
</bean>
<!--省略配置sqlSessionFactoryBean-->
<!--省略配置DAO 以及 业务Bean配置-->
<!--省略事务管理配置-->
注意:
使用
<util-properties/>
标签时,取属性文件的值时需使用#
+属性文件的id.key名,例如:#{db.driver}
database.properties
属性文件内容如下:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/foo?useUnicode=true&characterEncoding=utf-8
username=root
password=root
> 扩展使用配置类的方式:
AppConfig.java
代码如下:
@Configuration
@ComponentScan("cn.foo.service")
@MapperScan("cn.foo.dao")
@PropertySource("classpath:database.properties")//扫描属性文件
@EnableTransactionManagement//启动Spring管理事务
public class AppConfig {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean
public DataSource dataSource(){
BasicDataSource dataSource = new BasicDataSource();
//dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setDriverClassName(driver);
//dataSource.setUrl("jdbc:mysql://localhost:3306/foo?useUnicode
// =true&characterEncoding=utf-8");
dataSource.setUrl(url);
//dataSource.setUsername("root");
dataSource.setUsername(username);
//dataSource.setPassword("root");
dataSource.setPassword(password);
return dataSource;
}
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean =
new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource());
sqlSessionFactoryBean.setTypeAliasesPackage("cn.foo.pojo");
return sqlSessionFactoryBean.getObject();
}
@Bean
public DataSourceTransactionManager transactionManager(){
return new DataSourceTransactionManager(dataSource());
}
}
1.2 使用JNDI 数据源:
如果应用部署再高性能的应用服务器(如Tomcat WebLogic等)上,我们可能更希望应用服务器本身提供的数据源.应用服务器的数据源使用JNDI方式供使用者调用.Spring为此专门提供了引用JNDI资源的 JndiObjectFactoryBean 类.
使用JNDI 的方式配置数据源,前提是必须在应用服务器上配置好数据源. 以Tomcat为例,配置数据源要把数据库驱动文件放到 Tomcat 的lib目录下,并修改Tomcat的conf 目录中的 context.xml文件,配置数据源代码如下:
<Context>
<Resource name="jdbc/foo" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000" username="root"
password="root" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/foo?useUnicode=true&characterEncoding=utf-8"/>
</Context>
<Resouce>
标签中的name属性指定了数据源的名称,要与Spring配置文件中的jndiName值 java:comp/env/ 后面的名称保持一致. 关于<Resource>
标签中的其他参数的详细配置以及 参数说明可参考官网:http://tomcat.apache.org/tomcat-9.0-doc/jndi-resources-howto.html#JDBC_Data_Sources
.
Spring 配置文件内容如下:
<!--通过JNDI配置DataSource-->
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<!--将resourceRef属性设置为true可省略java:comp/env/-->
<!-- <property name="resourceRef" value="true"/>-->
<!--通过jndiName 指定引用 JNDI 数据源的名称-->
<property name="jndiName" value="java:comp/env/jdbc/foo"/>
</bean>
<!--使用第二种方式配置JNDI 需要引入jee命名空间-->
<!-- <jee:jndi-lookup jndi-name="java:comp/env/jdbc/foo" id="dataSource"/> -->
<!--省略配置sqlSessionFactoryBean-->
<!--省略配置DAO 以及 业务Bean配置-->
<!--省略事务管理配置-->
使用第二种方式可参照Spring的官网:https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/data-access.html
详细代码如下:
<jee:jndi-lookup jndi-name="jdbc/foo" id="dataSource"/>
<!--省略配置sqlSessionFactoryBean-->
<!--省略配置DAO 以及 业务Bean配置-->
<!--省略事务管理配置-->
1.3 在web环境中测试使用JNDI获得数据源对象
在
pom.xml
文件中将项目的打包状态改为war
, 并加如servlet-api
的jar包 , 关键代码如下:<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cn.foo</groupId> <artifactId>ssm_ch08</artifactId> <!--将项目打包的状态修改为war包 --> <packaging>war</packaging> <dependencies> <!--省略其他jar包的依赖 --> <!--servlet-api--> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> </dependencies> </project>
因为Java Web 的 Maven 基本结构如下:
结构说明:src
:源码目录src/main/java
:Java 源码目录src/main/resources
:资源文件目录src/main/webapp
:Web 相关目录src/test
:单元测试所以构建web项目的目录 , 需要在项目
src/main
目录下 , 创建webapp
目录 , 并在webapp
目录下创建WEB-INF
目录 ,WEB-INF
目录中创建web.xml
文件 , 内容可参照tomcat\webapps\ROOT\WEB-INF
目录下的web.xml文件 .
创建
UserServlet
, 代码如下:/** * 测试Spring与MyBatis的整合 */ public class UserServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8"); ApplicationContext ac = new ClassPathXmlApplicationContext( "applicationContext.xml"); ac.getBean(UserService.class).findUserList().forEach(System.out::println); //此处只为获取到业务层的数据,故省略其他业务逻辑s req.getRequestDispatcher("index.jsp").forward(req,resp); } }
index.jsp
页面如下:web.xml
配置如下: ```xml <?xml version=”1.0” encoding=”UTF-8”?>使用JNDI数据源 jdbc/foo javax.sql.DataSource Container user cn.foo.web.UserServlet 1 user *.do index.do
<br />关于`resource-ref`具体配置以及参数说明 可参照[官网](http://tomcat.apache.org/tomcat-9.0-doc/jndi-resources-howto.html) : `http://tomcat.apache.org/tomcat-9.0-doc/jndi-resources-howto.html`
4. 配置tomcat , 并将项目部署到服务器中 , 运行项目 , 控制台输出信息 , 若发现控制台中文乱码 , 在配置tomcat时,找到`VM options`,添加一行字符:`-Dfile.encoding=utf-8`,并且在IDEA中点击Help,选择,文件末尾添加一行字符:`-Dfile.encoding=utf-8`,重启IDEA,即可解决控制台中文乱码。
<a name="fbbb2750"></a>
### > 注意:
- 若工具使用的是**IDEA** ,创建的是普通的`Web`项目 , 而不是`Maven`项目, 则必须将 Tomcat的conf目录下的context.xml文件复制一份 到 项目目录下的**META-INF**目录下,以保证**IDEA**能够扫描到该文件,同时去掉除了配置的`<Resource>`标签之外的其他标签;
- 需在Web环境下测试使用JNDI获得数据源对象.可将测试代码写在Servlet中,或者也可以使用我们后期要讲到的SpringMVC框架整合Spring 以及 MyBatis框架进行测试;
通过以上示例我们发现,通过JNDI获取的数据源代码很简洁,这充分体现了Spring追求实用,简洁的目标
<a name="7815dc5e"></a>
### > 扩展配置类:
配置类中使用JNDI获取数据源 , 代码如下:
`AppConfig.java:` 配置JNDI的第一种方式:
```java
//省略其他代码
/*配置JNDI的第一种方式:*/
@Bean
public DataSource dataSource(){
JndiObjectFactoryBean jndiObjectFactoryBean =
new JndiObjectFactoryBean();
jndiObjectFactoryBean.setResourceRef(true);
jndiObjectFactoryBean.setJndiName("jdbc/foo");
jndiObjectFactoryBean.setProxyInterface(DataSource.class);
try {
// 调用 afterPropertiesSet 方法之后,才去查找 JNDI
jndiObjectFactoryBean.afterPropertiesSet();
} catch (NamingException e) {
e.printStackTrace();
}
return ((DataSource) jndiObjectFactoryBean.getObject());
}
//省略其他代码
AppConfig.java:
配置JNDI的第二种方式:
/**
* 第二种方式
* @return
*/
@Bean
public JndiObjectFactoryBean jndiObjectFactoryBean(){
JndiObjectFactoryBean jndiObjectFactoryBean =
new JndiObjectFactoryBean();
jndiObjectFactoryBean.setResourceRef(true);
jndiObjectFactoryBean.setJndiName("jdbc/foo");
jndiObjectFactoryBean.setProxyInterface(DataSource.class);
return jndiObjectFactoryBean;
}
/**
* 注入 JndiObjectFactoryBean 实例化后的 bean,再获取 DataSource
* @return
*/
@Bean
public DataSource dataSource(){
return ((DataSource) jndiObjectFactoryBean().getObject());
}
推荐使用第二种 , 原因在于:JndiObjectFactoryBean 真正的 lookup jndi 是在Spring获取JndiObjectFactoryBean实例化的bean后,再调用 JndiObjectFactoryBean 的 afterPropertiesSet 方法去完成的。
2 . Spring 中 Bean 的作用域问题
2.1 理解 Bean 的作用域问题
在Spring中定义Bean,除了可以创建Bean实例并对Bean属性进行注入外,还可以为所定义的Bean指定一个作用域.这个作用域的取值决定了Spring创建该组件实例的策略,进而影响程序的运行效率和数据安全,在Spring 2.0 以及之后的版本中,Bean的作用域被划分为5种,如图所示:
作用域 | 说 明 |
---|---|
singleton | 默认值。Spring以单例模式创建Bean的实例,即容器中该Bean的实例只有一个 |
prototype | 每次从容器中获取Bean时,都会创建一个新的实例 |
request | 用于Web应用环境,针对每次HTTP请求都会创建一个实例 |
session | 用于Web应用环境,同一个会话共享同一个实例,不同的会话使用不同的实例 |
global session | 仅在Portlet的Web应用中使用,同一个全局会话共享一个实例。对于非Portlet环境,等同于session |
singleton 是默认采用的作用域,即默认情况下Spring为每个Bean仅创建一个实例.对于不存在线程安全问题的组件,采用这种方式可以大大减少创建对象的开销,提高运行效率.
而对于存在线程安全问题的组件,则不能使用singleton模式,可以使用prototype作用域,通过scope属性,关键代码如下:
<!-- 指定Bean的作用域为prototype -->
<bean id="...." class="...." scope="prototype">
.....
</bean>
这样 Spring 在每次创建该组件时,都会创建一个新的实例,避免因为共用同一个实例而产生线程安全问题.
对于web环境下使用request,session,global session 作用域,其配置细节会在后续课程中用到时再详细讲解,这里先做一下了解即可.
2.2 使用注解指定Bean的作用域
对于使用注解声明的Bean组件, 如需修改其作用域,可以使用@Scope 注解实现.关键代码如下:
@Scope("prototype")
//@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Service
public class UserServiceImpl implements UserService {
//省略其他代码
}
3 . Spring 的自动装配
之前章节中介绍通过@Autowired 或 @Resource 注解实现依赖注入时,曾经提到Spring的自动装配功能.在没有显式指定所依赖的Bean组件id的情况下,通过自动装配,可以将与属性类型相符的(对于@Resource注解而言还会尝试id和属性名相符的)Bean自动注入给属性,从而简化配置;
不仅通过注解实现依赖注入时可以使用自动装配,基于XML的配置中也同样可以使用自动装配简化配置.
采用传统的XML方式配置Bean组件的代码如下所示:
<!-- 省略 DataSource 和 SqlSessionFactoryBean的配置-->
<!-- 配置DAO -->
<bean id="userMapper" class="cn.foo.dao.user.impl.UserMapperImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
<!--配置业务Bean 并注入 DAO 实例-->
<bean id="userService" class="cn.foo.service.user.impl.UserServiceImpl">
<property name="userMapper" ref="userMapper"/>
</bean>
在这里,我们通过<property>
标签为Bean的属性注入所需要的值,当需要维护的Bean组件以及需要注入的属性增多时,势必会增加配置的工作量.
使用自动装配修改配置代码,配置文件代码如下:
<!-- 省略 DataSource 和 SqlSessionFactoryBean的配置-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--配置sqlSessionFactoryBean-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--引用数据源组件-->
<property name="dataSource" ref="dataSource"/>
<!--引用MyBatis配置文件中的配置-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!--为实体类 指定映射别名-->
<!--<property name="typeAliasesPackage" value="cn.foo.pojo"/>-->
<!--配置SQL映射文件的信息 不使用mapper-->
<property name="mapperLocations"
value="classpath*:cn/foo/dao/**/*.xml" />
</bean>
<!--配置DAO 根据属性名称自动装配-->
<bean id="userMapper"
class="cn.foo.dao.user.impl.UserMapperImpl"
autowire="byName" />
<!--配置业务Bean 根据属性名称自动装配-->
<bean id="userService" class="cn.foo.service.user.impl.UserServiceImpl" autowire="byName">
</bean>
通过设置<bean>
元素中的autowire属性指定自动装配,代替了通过<property>
标签显式指定Bean的依赖关系.这就是Spring自动装配的神奇之处,由BeanFactory 检查 XML 配置文件的内容,为Bean自动注入依赖关系,大大简化了维护Bean注入的配置.
Spring提供的4种自动装配类型autowire的属性常用的取值如表:
取值 | 说明 |
---|---|
no | 默认值。Spring默认不进行自动装配,必须显式指定依赖对象 |
byName | 根据属性名自动装配。Spring自动查找与属性名相同的id,如果找到,则自动注入,否则什么都不做 |
byType | 根据属性的类型自动装配。Spring自动查找与属性类型相同的Bean,如果刚好找到唯一的那个,则自动注入;如果找到多个与属性类型相同的Bean,则抛出异常;如果没找到,就什么也不做 |
constructor | 和byType 类似,不过它针对构造方法。如果Spring找到一个Bean和构造方法的参数类型相匹配,则通过构造注入该依赖对象;如果找不到,将抛出异常 |
> 问题
在Spring配置文件中 通过<bean>
元素的autowire属性可以实现自动装配.但是,如果要自动装配的Bean很多,每个Bean若都配置autowire属性,则会变得很繁琐,可不可以统一设置自动注入而不必配置每个Bean呢?
> 解决方案:
<beans>
元素提供了default-autowire 属性. 可以使用上表中的属性值为<beans>
设置default-autowire属性,影响全局,减少维护单个Bean的注入方式.
修改Spring 配置文件,设置全局自动装配,代码如下:
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd"
default-autowire="byName">
<!-- 省略其他代码 -->
</beans>
在<beans>
节点上设置default-autowire时,<bean>
节点上依然可以设置autowire属性.这时该<bean>
节点上的自动装配设置将覆盖全局配置,成为该Bean的自动装配策略.
经验:
对于大型应用,不鼓励使用自动装配.虽然使用自动装配使得配置文件可以非常简洁,但同时也造成组件之间的依赖关系不明确,容易引发一些潜在的错误,所以,在实际项目中要谨慎使用
4 . 拆分Spring配置文件
为什么需要拆分配置文件?
项目规模变大,配置文件可读性、可维护性差
团队开发时,多人修改同一配置文件,易发生冲突
4.1 拆分策略
- 公用配置 + 每个系统模块一个单独配置文件(包含DAO、Service、Web控制器)
- 公用配置+DAO Bean配置+业务逻辑Bean配置+Web控制器配置
两种策略各有特色,适用于不同场合
4.2 拆分方法
两种方法
第一种:
利用ClassPathXmlApplicationContext的重载构造方法可以配置多个配置文件,用逗号隔开或者使用通配符
方法如下:
- public ClassPathXmlApplicationContext(String configLocation);
- public ClassPathXmlApplicationContext(String… configLocations);
如果有多个配置文件需要载入,可以分别传入多个配置文件,代码如下:
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("applicationContext.xml",
"applicationContext-dao.xml",
"applicationContext-service.xml");
//省略其他代码
使用注解:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"
,"classpath:applicationContext-dao.xml",
"classpath:applicationContext-service.xml"})
public class TestUserService {
//省略其他代码
}
使用通配符(*
)来加载多个具有一定命名规则的配置文件,代码如下:
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("classpath*:applicationContext*.xml");
//省略其他代码
注解通配符:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath*:applicationContext*.xml")
public class TestUserService {
//省略其他代码
}
经验:
实际项目开发过程中,建议通过通配符(*****
)的方式配置多个Spring配置文件.为了方便采用通配符,建议在给Spring配置文件命名时遵循一定的规律
第二种:使用<import resource="xxx.xml"/>
方式
Spring 配置文件本身也可以通过 <import>
子元素导入其他配置文件,将多个配置文件整合到一起,形成一个完整的Spring配置文件. 例如 : 在applicationContext.xml文件中添加如下代码,则只需引用applicationContext.xml即可加载所有的配置文件。
<!-- 省略其他代码 -->
<!-- 导入多个Spring 配置文件 -->
<import resource="classpath:applicationContext-dao.xml"/>
<import resource="classpath:applicationContext-service.xml"/>
<!-- 省略其他代码 -->
测试代码如下:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class TestUserService {
private final Logger logger = Logger.getLogger(this.getClass());
@Autowired
private UserService userService;
@Test
public void testGetUserList(){
List<User> userList = userService.findUserList();
userList.forEach(logger :: info);
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("applicationContext.xml");
// 获取容器中定义的所有的Bean的名称
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
logger.info(Arrays.toString(beanDefinitionNames));
}
}
4.3 配置类实现:
AppConfig.class代码如下:
@Configuration
@MapperScan("cn.foo.dao")
@PropertySource("classpath:database.properties")//扫描属性文件
public class AppConfig {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean
public DataSource dataSource(){
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean =
new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource());
sqlSessionFactoryBean.setTypeAliasesPackage("cn.foo.pojo");
return sqlSessionFactoryBean.getObject();
}
}
AppServiceConfig.java代码如下:
@ComponentScan("cn.foo.service")
@EnableTransactionManagement//<tx:annotation-driven />
@Import(AppConfig.class)//导入配置类 代替<import resource="classpath:applicationContext-dao.xml"/>
public class AppServiceConfig {
@Autowired
private DataSource dataSource;
//<!--定义事务管理器的Bean-->
@Bean
public TransactionManager transactionManager(){
return new DataSourceTransactionManager(dataSource);
}
}
测试类代码如下:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppServiceConfig.class)
public class TestUserService {
private final Logger logger = Logger.getLogger(this.getClass());
@Autowired
private UserService userService;
@Test
public void testGetUserList(){
List<User> userList = userService.findUserList();
userList.forEach(logger :: info);
}
}