之前我们只是使用Junit的测试注解 @Test,并没有使用Spring对于Junit的支持
Spring6既支持Junit4、也支持Spring5
要想使用Spring对于Junit的支持,我们需要在pom中导入相关依赖
org.springframework spring-test 6.0.0-M2
因为 Spring6 还没有正式发布,所以我们需要配置对应的远程仓库
repository.spring.milestone Spring Milestone Repository https://repo.spring.io/milestone
上面对Junit支持的依赖是既可以用于Junit4、也可以用于Junit5的,我们选择使用4还是5只需要导入相关依赖
org.junit.jupiter junit-jupiter 5.9.0 test
junit junit 4.13.2 test
为了具体演示测试类的不同,我们编写一个User类,提供一个获取名字的方法
编写我们的 User 类
package com.powernode.spring6.bean;import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;/*** @author Bonbons* @version 1.0*/
@Component
public class User {// 我们只提供一个属性@Value("华佗")private String name;public User() {}public User(String name) {this.name = name;}public void setName(String name) {this.name = name;}public String getName() {return name;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +'}';}
}
编写我们的配置文件 >> 因为我们采用注解恶毒方式声明Bean和注入属性值,所以需要扫描一下
我们先编写一下我们使用Junit4支持的测试类
package com.powernode.spring6.test;import com.powernode.spring6.bean.User;import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;/*** @author Bonbons* @version 1.0*/
@RunWith(SpringJUnit4ClassRunner.class) //RunWith是一个运行器,我们可以指定让Junit4来运行
@ContextConfiguration("classpath:spring.xml") // 该注解声明我们配置文件的位置,类中所有方法都可以直接使用Spring容器
public class SpringJunit4Test {// 可以直接创建全局对象 >> 使用@Autowired注解按类型注入@Autowiredprivate User user;@Testpublic void testUser(){/*我们每次进行单元测试都要获取Spring容器,然后通过getBean获取对象实例 >> 很不方便Spring对Junit4提供了支持,我们直接可以给我们的测试类添加两个注解 >> 代替这些繁琐的步骤*//*ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");User user = applicationContext.getBean("user", User.class);System.out.println(user.getName());*/// 以上注释掉的代码可以用下面的代替System.out.println(user.getName());}
}
编写我们 Junit5 的测试类 >> 我们需要在pom.xml中使用Spring对Junit支持的依赖以及Junit5的依赖
package com.powernode.spring6.test;import com.powernode.spring6.bean.User;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;/*** @author Bonbons* @version 1.0*/
@ExtendWith(SpringExtension.class)
@ContextConfiguration("classpath:spring.xml")
public class SpringJunit5Test {// 直接将User类作为成员变量使用@Autowiredprivate User user;@Testpublic void testUser(){System.out.println(user.getName());}
}
在数据库中准备一张操作的表,我们还是使用 t_act2
创建一个新的模块 spring6-016-sm,并完成相关依赖的配置
4.0.0 com.powernode spring6-016-sm 1.0-SNAPSHOT jar repository.spring.milestone Spring Milestone Repository https://repo.spring.io/milestone org.springframework spring-context 6.0.0-M2 org.springframework spring-jdbc 6.0.0-M2 mysql mysql-connector-java 8.0.30 org.mybatis mybatis 3.5.11 org.mybatis mybatis-spring 2.0.7 com.alibaba druid 1.2.13 junit junit 4.13.2 test 17 17 UTF-8
采用MVC三层架构建包 >> 但是我们还是Jar项目,以测试程序代替表现层 【我直接给出了所有文件的目录结构】
编写我们的普通 java 类 >> 用来封装我们数据库表中的字段 Account
package com.powernode.bank.pojo;/*** @author Bonbons* @version 1.0*/
public class Account {private String actno;private Double balance;public Account() {}public Account(String actno, Double balance) {this.actno = actno;this.balance = balance;}@Overridepublic String toString() {return "Account{" +"actno='" + actno + '\'' +", balance=" + balance +'}';}public String getActno() {return actno;}public void setActno(String actno) {this.actno = actno;}public Double getBalance() {return balance;}public void setBalance(Double balance) {this.balance = balance;}
}
编写我们的Mapper接口 >> 就是对数据库表进行操作的接口,我们采用,MyBatis为我们提供了接口可以动态生成Mapper实现类
package com.powernode.bank.mapper;import com.powernode.bank.pojo.Account;import java.util.List;/*** @author Bonbons* @version 1.0*/
public interface AccountMapper {// 提供简单的增删改查int insert(Account account);int deleteByActno(String actno);int update(Account account);Account selectByActno(String actno);List selectAll();
}
我们为了一次能导入所有xml配置文件,就将Mapper接口与映射文件放在一个目录下,注意命名的时候用正斜杠
然后编写我们的映射文件 >> 就是写SQL语句的地方 【此处的查询返回值类型我用别名了,因为在核心配置文件中我会开启自动映射】
insert into t_act2 values(#{actno}, #{balance}) delete from t_act2 where actno = #{actno} update t_act2 set balance = #{balance} where actno = #{actno}
编写业务层的接口 AccountService
package com.powernode.bank.service;import com.powernode.bank.pojo.Account;import java.util.List;/*** @author Bonbons* @version 1.0*/
public interface AccountService {// 添加用户int save(Account account);// 删除用户int delete(String actno);// 修改用户信息int modify(Account account);// 查询一条用户信息Account getByActno(String actno);// 查询全部的用户信息List getAll();// 转账void transfer(String fromActno, String toActno, Double money);
}
编写我们业务接口的实现类AccountServiceImpl,通过注解纳入Spring IoC 容器托管
package com.powernode.bank.service.impl;import com.powernode.bank.mapper.AccountMapper;
import com.powernode.bank.pojo.Account;
import com.powernode.bank.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.util.List;/*** @author Bonbons* @version 1.0*/
@Service("accountService")
@Transactional
public class AccountServiceImpl implements AccountService {// 引入数据库的操作接口@Autowiredprivate AccountMapper accountMapper;@Overridepublic int save(Account account) {return accountMapper.insert(account);}@Overridepublic int delete(String actno) {return accountMapper.deleteByActno(actno);}@Overridepublic int modify(Account account) {return accountMapper.update(account);}@Overridepublic Account getByActno(String actno) {return accountMapper.selectByActno(actno);}@Overridepublic List getAll() {return accountMapper.selectAll();}@Overridepublic void transfer(String fromActno, String toActno, Double money) {// 获取转出账户Account fromAct = accountMapper.selectByActno(fromActno);// 判断余额是否充足if (fromAct.getBalance() < money) {throw new RuntimeException("余额不足!!!");}// 获取转入账户Account toAct = accountMapper.selectByActno(toActno);// 更新内存中账户余额fromAct.setBalance(fromAct.getBalance() - money);toAct.setBalance(toAct.getBalance() + money);// 写入到数据库中int count = accountMapper.update(fromAct);count += accountMapper.update(toAct);if (count != 2) {throw new RuntimeException("转账失败!!!");}}
}
为了方便维护,我们将数据源的连接属性独立迟来成为一个配置文件 jdbc.properties
jdbc.driver = com.mysql.cj.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/powernode
# 这里不要直接使用username,因为默认获取的是当前计算机的用户名
jdbc.username = root
jdbc.password = 111111
编写我们MyBatis的核心配置文件,此处我们就做一个设置开启打印日志功能,重要的配置我们直接在spring的配置文件中进行配置
编写我们spring的配置文件,具体工作我利用注释标记了
编写测试程序,因为我们就想看配置是否成功以及能否成功转账,所以我们不配置Spring对junit的支持了
package com.powernode.bank.test;import com.powernode.bank.service.AccountService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import java.lang.reflect.AccessibleObject;/*** @author Bonbons* @version 1.0*/
public class SMTest {@Testpublic void test(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");AccountService accountService = applicationContext.getBean("accountService", AccountService.class);accountService.transfer("act-001", "act-002", 1000.0);}
}
简单工厂模式
工厂方法模式
单例模式
代理模式
装饰器模式
观察者模式
策略模式
模板方法模式