Spring---整合第三方框架
整合Junit
原始Junit测试Spring的问题
在测试类中,每个测试方法都有以下两行代码:
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
IAccountService as = ac.getBean("accountService",IAccountService.class);
这两行代码的作用是获取容器,如果不写的话,直接会提示空指针异常。所以又不能轻易删掉。
上述问题解决思路
让SpringJunit负责创建Spring容器,
但是需要将配置文件的名称告诉它,将需要进行测试Bean直接在测试类中进行注入
Spring集成Junit步骤
- 导入spring集成Junit的坐标
- 使用@Runwith注解替换原来的运行期
- 使用@ContextConfiguration指定配置文件或配置类
- 使用@Autowired注入需要测试的对象
- 创建测试方法进行测试
代码实现
- 导入spring集成Junit的坐标
<!--此处需要注意的是,spring5 及以上版本要求 junit 的版本必须是 4.12 及以上-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
- 使用@Runwith注解替换原来的运行期
@RunWith(SpringJUnit4ClassRunner.class)
public class SpringJunitTest {
}
- 使用@ContextConfiguration指定配置文件或配置类
@RunWith(SpringJUnit4ClassRunner.class)
//加载spring核心配置文件
//@ContextConfiguration(value = {"classpath:applicationContext.xml"})
//加载spring核心配置类
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {
}
- 使用@Autowired注入需要测试的对象
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {
@Autowired
private UserService userService;
}
- 创建测试方法进行测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {
@Autowired
private UserService userService;
@Test
public void testUserService(){
userService.save();
}
}
整合JdbcTemplate
传统JdbcTemplate操作数据库
- 步骤一: 导入依赖, spring-jdbc依赖(前提导入mysql驱动依赖,导入数据库连接池依赖)
- 步骤二: JdbcTemplate核心api操作数据库(没有整合前)
//1.创建模板对象
JdbcTemplate jt = new JdbcTemplate(数据库连接池对象)
//2.调用查询方法和更新方法操作数据库
List<T> list = jt.query(sql,结果集处理器, 给sql语句赋值);//查询所有
int row = jt.query(sql,给sql语句赋值)
Spring容器管理JdbcTemplate模板对象
- 步骤一: 通过@Bean注解, 在容器中初始化DataSource数据库连接池对象
/**
* 类: 初始化数据库连接池,存到容器里面
*/
@PropertySource("classpath:db.properties")
@Configuration//可加,可不加, 表示第三方类
public class DataSourceConfig {
@Value("${jdbc.driverClassName}")
private String driverClassName;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean("dataSource")
public DataSource getDruidDataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName(driverClassName);
ds.setUrl(url);
ds.setUsername(username);
ds.setPassword(password);
return ds;
}
}
- 步骤二: 通过@Bean注解, 在容器中初始化JdbcTemplate对象.
@Import(DataSourceConfig.class)
@Configuration
public class JDBCTemplateConfig {
/**
* @Autowired DataSource dataSource): 通过参数注入数据库连接池对象, 模板类可以直接使用
* @param dataSource
* @return
*/
@Bean("jdbcTemplate")
public JdbcTemplate getJdbcTemplate(@Autowired DataSource dataSource){
JdbcTemplate jt = new JdbcTemplate(dataSource);
return jt;
}
}
- 步骤三: 通过@Import注解,在配置类里面导入上述两个@Bean外部的类
@ComponentScan("com.jt.dao")
@Configuration
@Import({JDBCTemplateConfig.class})
public class SpringConfig2 {
}
- 步骤四: 测试
public interface UserDao {
List<User> findAll();
}
@Repository
public class UserDaoImpl implements UserDao {
//注入模板类
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public List<User> findAll(){
String sql = "select * from tab_user";
List<User> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<User>(User.class));
return list;
}
}
//spring-test: 提供的类SpringJUnit4ClassRunner
@RunWith(SpringJUnit4ClassRunner.class)
//SpringJUnit4ClassRunner加载配置文件或者配置类:SpringConfig1
//会自动初始化容器对象,会自动进行包扫描,将bean对象存到容器中
@ContextConfiguration(classes = {SpringConfig2.class})
public class DemoJdbcTemplateTest {
@Autowired
private UserDao dao;
@Test
public void testX(){
List<User> all = dao.findAll();
System.out.println(all);
}
}
整合mybatis
传统mybatis基于接口操作数据库
- 步骤一: 给接口进行代理(JDK),生成代理对象
//1.得到工厂对象: SqlSessionFactory
//2.通过工厂对象得到: SqlSession
//3.得到代理对象: getMapper(接口的自己码对象)方法,获取代理对象
- 步骤二: 通过代理对象操作数据库.
小结:代理对象不是spring容器生成的,而是由mybatis通过代理生成的.
Spring整合mybatis(本质: mybatis生成代理对象,交给spring容器管理)
- 步骤一: 导入依赖: mybatis依赖, 导入spring整合mybatis依赖
<!--引入mybatis自身依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<!--引入spring整合mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
如果需要在控制台打印sql语句,需要引入日志依赖以及日志的配置文件 log4j.properties
# 全局日志配置 日志信息的优先级从高到低有ERROR、WARN、 INFO、DEBUG,
log4j.rootLogger=DEBUG, stdout
# 控制台输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
在pom.xml
文件引入日志依赖
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
- 步骤二: 通过@Bean注解,生成获取代理对象的第三方类
/**
* 类: 初始化数据库连接池,存到容器里面
*/
@PropertySource("classpath:db.properties")
@Configuration//可加,可不加, 表示第三方类
public class DataSourceConfig2 {
@Value("${jdbc.driverClassName}")
private String driverClassName;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean("dataSource")
public DataSource getDruidDataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName(driverClassName);
ds.setUrl(url);
ds.setUsername(username);
ds.setPassword(password);
return ds;
}
}
@Import({DataSourceConfig2.class})
public class MyBatisConfig {
/**定义bean:SqlSessionFactoryBean,用于产生SqlSessionFactory对象
* SqlSessionFactoryBean是FactoryBean的一个子类,
* 也是mybatis-spring整合jar包中的类,该类将SqlSessionFactory的创建进行了封装,简化对象的创建,
* @param druidDataSource
* @return
*/
@Bean
public SqlSessionFactoryBean sqlSessionFactory(@Autowired DataSource druidDataSource){
SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
//设置模型类的别名扫描
ssfb.setTypeAliasesPackage("com.domain");
//设置数据源:mybatis框架使用第三方的数据库连接池
ssfb.setDataSource(druidDataSource);
return ssfb;
}
/**
* MapperScannerConfigurer也是MyBatis和spring整合依赖提供类,
* 用来处理原始mapper映射文件相关配置,加载数据层的Mapper(Dao)接口类。
* 核心属性basePackage,就是用来设置所扫描的包路径
* @return
*/
/**
* 底层实现:
* 1. MapperScannerConfigurer: 只扫描dao(包),获取dao目录下面的接口
* 2. SqlSessionFactoryBean得到SqlSessionFactory, 获取SqlSession对象
* 3. 根据第一步获取的结果,遍历包下面的所有接口
* 根据第二步获取的SqlSession,对接口进行代理,生成接口的代理对象
* UserDao mapper = sqlSession.getMapper(UserDao.class)
* 存到spring容器中
* @return
*/
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer msc = new MapperScannerConfigurer();
msc.setBasePackage("com.mybatis.dao");
return msc;
}
}
- 步骤三: 在SpringConfig的配置文件里面引入@Bean注解的外部类
@ComponentScan("com.mybatis")
@Configuration
@Import({MyBatisConfig.class})
public class SpringConfig4 {
}
- 步骤四: 测试
// 通过MapperScannerConfigurer扫描@Mapper,创建bean对象,存到容器中
@Mapper
public interface UserDao2 {
@Select("select * from tab_user")
List<User> findAll();
}
//由于接口的代理对象已经初始化容器中,可以其它位置进行注入(DI的基础就是IOC)
@Service
public class UserServiceImpl implements UserService {
//1.注入dao
@Autowired
private UserDao2 dao ;
@Override
public List<User> findUsers(){
return dao.findAll();
}
}
//spring-test: 提供的类SpringJUnit4ClassRunner
@RunWith(SpringJUnit4ClassRunner.class)
//SpringJUnit4ClassRunner加载配置文件或者配置类:SpringConfig1
//会自动初始化容器对象,会自动进行包扫描,将bean对象存到容器中
@ContextConfiguration(classes = {SpringConfig4.class})
public class DemoMyBatisTest {
@Autowired
private UserService userService;
@Test
public void testX(){
List<User> users = userService.findUsers();
System.out.println(users);
}
}