Spring 是一个java 项目开发的框架技术
所谓框架可以看成一个项目的半成品,已经具备了一个项目项目的基本骨架部分,需要自己实现一些具体的内容
Spring官网
Spring技术的优势:
1、能够简化开发:
2、能够整合框架
- Mybatis
- MyBatis-plus
- Struts
- Struts2
- Hibernate
- ……
Spring家族
Spring发展到今天已经形成了一套非常完整丰富的框架,市场上很多项目都基于Spring框架完成
初学Spring应该重点关注一下几种技术
- Spring Framework
- Spring boot 提高开发速度
- Spring Cloud 分布式开发相关技术
Spring Framework 简介
Spring Framework 是Spring生态圈其他项目的基础
Spring4.0 系统架构
编写项目的时候因为实现功能往往需要new对象,导致耦合度偏高(如DAO层原来的实现类有问题,现在重新编写了一个,在Service层实现时,需要调用DAO层对象,这时就需要new一个新的DAO实现类对象,这样代码就改变了,需要重新编译,重新部署)
- 解决方案 : 使用对象是,在程序中不要主动使用new 产生对象 转换为由外部提供对象 ,
- 即创建对象的控制权转换到外部,即控制反转 IoC (Inversion of Control)
- Spring 提供了一个容器,称为IoC容器,当来当IoC思想的外部;现在由原来的:主动 new产生对象,变成由IoC提供对象
- 现在由IoC提供对象的创建、初始化等一系列操作,被创建的或者被管理的对象 在IoC 容器中统称为 Bean
- 此外,IoC中把Service层和DAO层的对象都进行了封装管理,但是要注意,Service层是要依赖DAO层的实现的,这里Spring在 IoC容器中实现了二者的依赖关系的绑定, 即 DI (Dependency Injection) 依赖注入
IoC 入门
- IoC容器管理什么? bean对象也即Service层和DAO层的类对象
- 如何将被管理的对象告知IoC容器? 配置文件
- 如何获取IoC对象? 接口
- IoC对象如何获取bean? 接口中的方法
- 使用Spring获取那些坐标? pom.xml
实现步骤
- 1、导入Spring坐标
在pom文件中导入坐标,才能创建配置文件
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--1、配置pom文件导入Spring依赖-->
<!--2、配置xml文件中的bean-->
<!-- bean 标签表示配置bean id 是名字 class 表示对应类名-->
<bean id="bookDao" class="com.taotao.dao.impl.BookDaoImpl"/>
<bean id="bookService" class="com.taotao.service.impl.BookServiceImpl"/>
</beans>
public class APP2 {
public static void main(String[] args) {
// 获取 IoC容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
// // 获取bean
// BookDao bookDao = (BookDao) ctx.getBean("bookDao");
// bookDao.save();
BookService bookService = (BookService) ctx.getBean("bookService");
bookService.SaveAll();
}
}
DI 入门
- 1、基于IoC管理bean
- 2、Service中使用new形式创建的Dao对象是否保留?(调用service 方法时会自动new dao对象)(否)
- 3、怎么获取对象Dao对象?(提供方法)
- 4、Service 与Dao 之间的关系如何描述?(配置)
步骤
- 1、删除业务层 Service层中 使用 new的方式创建的Dao对象
- 2、提供set方法
public class BookServiceImpl implements BookService {
// 1 删除原来new 出来的Dao对象
private BookDao dao;
@Override
public void SaveAll() {
// BookDao dao = new BookDaoImpl();
dao.save();
System.out.println("BookServiceImpl …… All");
}
//2 提供对象set方法
public void setBookDao(BookDao bookDao){
this.dao = bookDao;
}
}
- 3、 配置 Service 层对象对 Dao层对象之间的依赖关系
<?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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">
<!--1、配置pom文件导入Spring依赖-->
<!--2、配置xml文件中的bean-->
<!-- bean 标签表示配置bean id 是名字 class 表示对应类名-->
<bean id="bookDao" class="com.taotao.dao.impl.BookDaoImpl"/>
<bean id="bookService" class="com.taotao.service.impl.BookServiceImpl">
<!--3、配种 Service 层对象与 Dao层对象之间的依赖关系-->
<!--这里前者表示 配置哪一个具体的属性(Service 类中属性的名称) ,后者ref 是对应的 id名字-->
<property name="bookDao" ref="bookDao"></property>
</bean>
</beans>
4、 可以重新运行APP2程序,输出一样的结果
bean
bean的基础配置
- bean 的别名 : name属性可以指定别名 别名用逗号分号或者空格分开 作用:在程序中既可以用id 引用也可以用 name引用
- bean 的作用范围: Spring 默认给我们创建的bean对象是单例的
- 如果想要非单例的 ,可以在xml 配置文件 将 该 bean属性 scope 指定为 prototype非单例 ; singleton :单例 (默认)
- 为什么bean默认为单例?可以复用的对象不必创建过多否则占用资源。一般封装实体的对象才用非单例
- bean 的实例化
-
spring bean对象的创建其实是用反射实现的,反射内部调用的是spring无参的构造方法
-
上面的案例使用反射机制 使用构造方法实例化bean对象的;创建实例化对象还可以采用静态工厂的方式创建,步骤如下
// 静态工厂
public class OrderDaoFactory {
public static OrderDao getOrderDao(){
return new OrderDaoImpl();
}
}
// Dao接口
public interface OrderDao {
public void order();
}
// Dao实现
public class OrderDaoImpl implements OrderDao {
@Override
public void order() {
System.out.println("order dao ...");
}
}
<bean id="orderDao" class="com.taotao.factory.OrderDaoFactory" factory-method="getOrderDao"/>
class指向工厂类对象,factory-menthod 指向 获取对象的方法。
public class APPForInstanceOrder {
public static void main(String[] args) {
// OrderDao orderDao = OrderDaoFactory.getOrderDao();
// orderDao.order();
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
OrderDao dao = (OrderDao) ctx.getBean("orderDao");
dao.order();
}
}
-
实例工厂创建bean对象(工厂对象得到对象采用实例方法,不是静态方法,即去掉上述案例中public static OrderDao getOrderDao() 的 static) 这样要得到对象就必须创建工厂对象,然后再用工厂对象得到想要的对象
- 配置 bean
先创建工厂的bean 然后创建 Dao bean
<bean id= "orderDaoFactory " class="com.taotao.factory.OrderDaoFactory "/>
<bean id="oderDao" factory-method = "getOrderDao" factory-bean="orderDaoFactory "/>
- 改进(针对第三种方法 获取对象方法经常不固定的形式的缺陷)
- 创建一个FactoryBean的类
public class OrderDaoFactoryBean implements FactoryBean<OrderDao>{
public UserDao getObject() throws Exception{
return new OrderDaoImpl();
}
public Class<?> getObjectType(){
return UserDao.class;
}
public boolean isSingleton(){
return false;//如果是true或者默认不写这个函数,为单例
}
}
-如此可以简化伤处bean为
<bean id="oderDao" class="com.taotao.factory.OrderDaoFactoryBean"/>
bean的生命周期
依赖注入
-
依赖注入的方式
-
setter 注入
-
setter注入:引用类型(最开始学的就是引用雷勇的依赖注入)
- 在bean中定义引用数据类型并提供对应的set方法
- 在配置文件中 使用property标签 ref 属性注入引用对象,多个引用就创建多个property标签
-
setter注入:简单类型
举例在 BookDaoImp中定义了基本类型的属性 ,并提供了setter方法
public class BookDaoImpl implements BookDao{
private int connectionNum;
private String databaseName;
public void book(){
System.out.println("Dao book...")
}
public void setConnectionNum(int connectionNum){
this.connectionNum=connectionNum;
}
public void setDatabaseName(String databaseName){
this.databaseName=databaseName;
}
}
这样的话在配置文件中,配置bean如下
<bean id ="bookDao" class="com.taotao.dao.impl.BookDaoImpl">
<property name="connectionNum" value="10"/>
<property name="databaseName" value="mysql"/>
</bean>
-
构造器注入(使用构造方法注入)
- 引用类型
```
- 简单类型
同上 <constructor-arg name=“connectionNum” value= “10”>
- 缺陷: 名字必须和形参一致,耦合度高
<constructor-arg type="int" value= “10”>
<constructor-arg type="java.lang.String" value= “mysql”>
<constructor-arg index="0" value= “10”>
<constructor-arg index="1" value= “mysql”>
-
构造方式的选择:
- 强制依赖使用构造器注入,避免出现null的结果
- 可选依赖使用setter 注入
- 自己开发推荐使用setter注入
依赖自动装配
集合注入
- 数组
- property 标签的 name 对应 属性名字
- 里面的 下一级标签代表类型 有 array(可以和list混用) set map props
<property name="array">
<array>
<value>100</value>
<value>200</value>
<value>300</value>
</array>
</property>
举例 :引入第三方 数据源对象管理
以阿里的 druid 数据库连接池对象为例
在pom文件中引入依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
在xml文件中管理相应的对象
<bean id = "dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<!-- 由于构造器方法参数不够 所以选择相应的 setter 方法进行注入-->
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/day17"/>
<property name="username" value="root"/>
<property name="password" value="1234"/>
</bean>
在APP方法里面执行
public class APP3 {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
DataSource ds = (DataSource) ctx.getBean("dataSource");
System.out.println(ds);
}
}
通过导入配置文件(加载properties文件) 进行对象管理
步骤1:准备properties配置文件
resources下创建一个jdbc.properties文件,并添加对应的属性键值对
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/spring_db
jdbc.username=root
jdbc.password=root
步骤2:开启context
命名空间
在applicationContext.xml中开context
命名空间
<?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"
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">
</beans>
在配置文件中使用context
命名空间下的标签来加载properties配置文件
<context:property-placeholder location="jdbc.properties"/>
使用${key}
来读取properties配置文件中的内容并完成属性注入
<?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"
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">
<context:property-placeholder location="jdbc.properties"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<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>
</beans>
注解开发
注解开发定义bean
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
@Component("bookDao")
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ..." );
}
}
纯注解开发模式
- 1、创建配置类
创建一个配置类SpringConfig
public class SpringConfig {
}
- 2、标识该类为配置类
在配置类上添加@Configuration
注解,将其标识为一个配置类,替换applicationContext.xml
@Configuration
public class SpringConfig {
}
在配置类上添加包扫描注解@ComponentScan
替换<context:component-scan base-package=""/>
@Configuration
@ComponentScan("com.taotao")
public class SpringConfig {
}
创建一个新的运行类AppForAnnotation
public class AppForAnnotation {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
System.out.println(bookDao);
BookService bookService = ctx.getBean(BookService.class);
System.out.println(bookService);
}
}
注解开发bean作用范围与生命周期管理
@Repository // 表示Dao层 的bean对象
//@Scope设置bean的作用范围
@Scope("prototype")
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ...");
}
}
@Repository
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ...");
}
@PostConstruct //在构造方法之后执行,替换 init-method
public void init() {
System.out.println("init ...");
}
@PreDestroy //在销毁方法之前执行,替换 destroy-method
public void destroy() {
System.out.println("destroy ...");
}
}
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
BookDao bookDao1 = ctx.getBean(BookDao.class);
BookDao bookDao2 = ctx.getBean(BookDao.class);
System.out.println(bookDao1);
System.out.println(bookDao2);
ctx.close(); //关闭容器
}
}
注解开发依赖注入
- 1、在BookServiceImpl类的bookDao属性上添加
@Autowired
注解 即可
@Service
public class BookServiceImpl implements BookService {
@Autowired
private BookDao bookDao;
// public void setBookDao(BookDao bookDao) {
// this.bookDao = bookDao;
// }
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
-
@Autowired可以写在属性上,也可也写在setter方法上,最简单的处理方式是写在属性上并将setter方法删除掉
-
为什么setter方法可以删除呢?
- 自动装配基于反射设计创建对象并通过暴力反射为私有属性进行设值
- 普通反射只能获取public修饰的内容
- 暴力反射除了获取public修饰的内容还可以获取private修改的内容
- 所以此处无需提供setter方法
-
@Autowired是按照类型注入,那么对应BookDao接口如果有多个实现类,比如添加BookDaoImpl2,按照类型注入就无法区分到底注入哪个对象,解决方案:按照名称注入
@Repository("bookDao")
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ..." );
}
}
@Repository("bookDao2")
public class BookDaoImpl2 implements BookDao {
public void save() {
System.out.println("book dao save ...2" );
}
}
- 当根据类型在容器中找到多个bean,注入参数的属性名又和容器中bean的名称不一致,这个时候该如何解决,就需要使用到
@Qualifier
来指定注入哪个名称的bean对象。
@Service
public class BookServiceImpl implements BookService {
@Autowired
@Qualifier("bookDao1")
private BookDao bookDao;
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
- @Qualifier注解后的值就是需要注入的bean的名称。
简单数据类型注入
@Repository("bookDao")
public class BookDaoImpl implements BookDao {
@Value("itheima")
private String name;
public void save() {
System.out.println("book dao save ..." + name);
}
}
注解读取properties配置文件
上述 value属性 会有一种感觉就是这个注解好像没什么用,跟直接赋值是一个效果,还没有直接赋值简单,所以这个注解存在的意义是什么?
-
@Value
一般会被用在从properties配置文件中读取内容进行使用,具体如何实现?
-
1、resource下准备properties文件
jdbc.properties
name=itheima888
-
2、使用注解加载properties配置文件,
在配置类上添加@PropertySource
注解
@Configuration
@ComponentScan("com.itheima")
@PropertySource("jdbc.properties")
public class SpringConfig {
}
-
3、使用@Value读取配置文件中的内容
@Repository("bookDao")
public class BookDaoImpl implements BookDao {
@Value("${name}")
private String name;
public void save() {
System.out.println("book dao save ..." + name);
}
}
IOC/DI注解开发管理第三方bean
前面定义bean的时候都是在自己开发的类上面写个注解就完成了,但如果是第三方的类,这些类都是在jar包中,我们没有办法在类上面添加注解,这个时候该怎么办?
遇到上述问题,我们就需要有一种更加灵活的方式来定义bean,这种方式不能在原始代码上面书写注解,一样能定义bean,这就用到了一个全新的注解==@Bean==。
在上述环境中完成对Druid
数据源的管理,具体的实现步骤为:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
注意:不能使用DataSource ds = new DruidDataSource()
因为DataSource接口中没有对应的setter方法来设置属性。
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
DataSource dataSource = ctx.getBean(DataSource.class);
System.out.println(dataSource);
}
}
为了避免SpringConfig 配置类此类的外部配置项太多,一般还是要单独写一个配置类,对于数据源的bean,我们新建一个JdbcConfig
配置类,并把数据源配置到该类下。
public class JdbcConfig {
@Bean
public DataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
ds.setUsername("root");
ds.setPassword("root");
return ds;
}
}
现在的问题是,这个配置类如何能被Spring配置类加载到,并创建DataSource对象在IOC容器中?
针对这个问题,有两个解决方案:
优化上述配置代码
public class JdbcConfig {
@Value("com.mysql.jdbc.Driver")
private String driver;
@Value("jdbc:mysql://localhost:3306/spring_db")
private String url;
@Value("root")
private String userName;
@Value("password")
private String password;
@Bean
public DataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(userName);
ds.setPassword(password);
return ds;
}
}
- 此外如果是引用类型变量的依赖注入,可以在 函数中 使用形参导入
public class JdbcConfig {
@Value("com.mysql.jdbc.Driver")
private String driver;
@Value("jdbc:mysql://localhost:3306/spring_db")
private String url;
@Value("root")
private String userName;
@Value("password")
private String password;
@Bean
public DataSource dataSource(BookDao bookDao){
System.out.println(bookDao);
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(userName);
ds.setPassword(password);
return ds;
}
}
Spring 整合 MyBatis
Spring整合Mybatis
第一件事是:Spring要管理MyBatis中的SqlSessionFactory
第二件事是:Spring要管理Mapper接口的扫描
具体该如何实现,具体的步骤为:
<dependency>
<!--Spring操作数据库需要该jar包-->
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<!--
Spring与Mybatis整合的jar包
这个jar包mybatis在前面,是Mybatis提供的
-->
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
//配置类注解
@Configuration
//包扫描,主要扫描的是项目中的AccountServiceImpl类
@ComponentScan("com.itheima")
public class SpringConfig {
}
在配置类中完成数据源的创建
public class JdbcConfig {
@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(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(userName);
ds.setPassword(password);
return ds;
}
}
- 步骤4:主配置类中读properties并引入数据源配置类
@Configuration
@ComponentScan("com.itheima")
@PropertySource("classpath:jdbc.properties")
@Import(JdbcConfig.class)
public class SpringConfig {
}
- 步骤5:创建Mybatis配置类并配置SqlSessionFactory
public class MybatisConfig {
//定义bean,SqlSessionFactoryBean,用于产生SqlSessionFactory对象
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
//设置模型类的别名扫描
ssfb.setTypeAliasesPackage("com.itheima.domain");
//设置数据源
ssfb.setDataSource(dataSource);
return ssfb;
}
//定义bean,返回MapperScannerConfigurer对象
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer msc = new MapperScannerConfigurer();
msc.setBasePackage("com.itheima.dao");
return msc;
}
}
说明:
- 使用SqlSessionFactoryBean封装SqlSessionFactory需要的环境信息
-
SqlSessionFactoryBean是前面我们讲解FactoryBean的一个子类,在该类中将SqlSessionFactory的创建进行了封装,简化对象的创建,我们只需要将其需要的内容设置即可。
-
方法中有一个参数为dataSource,当前Spring容器中已经创建了Druid数据源,类型刚好是DataSource类型,此时在初始化SqlSessionFactoryBean这个对象的时候,发现需要使用DataSource对象,而容器中刚好有这么一个对象,就自动加载了DruidDataSource对象。
-
使用MapperScannerConfigurer加载Dao接口,创建代理对象保存到IOC容器中
- 这个MapperScannerConfigurer对象也是MyBatis提供的专用于整合的jar包中的类,用来处理原始配置文件中的mappers相关配置,加载数据层的Mapper接口类
- MapperScannerConfigurer有一个核心属性basePackage,就是用来设置所扫描的包路径
@Configuration
@ComponentScan("com.itheima")
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class,MybatisConfig.class})
public class SpringConfig {
}
在运行类中,从IOC容器中获取Service对象,调用方法获取结果
public class App2 {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
AccountService accountService = ctx.getBean(AccountService.class);
Account ac = accountService.findById(1);
System.out.println(ac);
}
}
- 步骤8:运行程序
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kH31owdY-1669383663408)(assets/1630139720273.png)]
支持Spring与Mybatis的整合就已经完成了,其中主要用到的两个类分别是:
- SqlSessionFactoryBean
- MapperScannerConfigurer
Spring整合Junit
整合Junit与整合Druid和MyBatis差异比较大,为什么呢?Junit是一个搞单元测试用的工具,它不是我们程序的主体,也不会参加最终程序的运行,从作用上来说就和之前的东西不一样,它不是做功能的,看做是一个辅助工具就可以了。
这块环境,大家可以直接使用Spring与Mybatis整合的环境即可。当然也可以重新创建一个,因为内容是一模一样,所以我们直接来看下项目结构即可:
在上述环境的基础上,我们来对Junit进行整合。
pom.xml
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
在test\java下创建一个AccountServiceTest,这个名字任意
//设置类运行器
@RunWith(SpringJUnit4ClassRunner.class)
//设置Spring环境对应的配置类
@ContextConfiguration(classes = {SpringConfiguration.class}) //加载配置类
//@ContextConfiguration(locations={"classpath:applicationContext.xml"})//加载配置文件
public class AccountServiceTest {
//支持自动装配注入bean
@Autowired
private AccountService accountService;
@Test
public void testFindById(){
System.out.println(accountService.findById(1));
}
@Test
public void testFindAll(){
System.out.println(accountService.findAll());
}
}
注意:
- 单元测试,如果测试的是注解配置类,则使用
@ContextConfiguration(classes = 配置类.class)
- 单元测试,如果测试的是配置文件,则使用
@ContextConfiguration(locations={配置文件名,...})
- Junit运行后是基于Spring环境运行的,所以Spring提供了一个专用的类运行器,这个务必要设置,这个类运行器就在Spring的测试专用包中提供的,导入的坐标就是这个东西
SpringJUnit4ClassRunner
- 上面两个配置都是固定格式,当需要测试哪个bean时,使用自动装配加载对应的对象,下面的工作就和以前做Junit单元测试完全一样了