Spring(二)——Junit测试工具、属性的注入方式、注解
文章目录
- 1. Junit 测试工具
- 2. getBean的五种用法
- 3. 属性的注入方式
- 4. bean的生存范围和加载策略
- 5. 自定义属性的注入方式
- 6. Spring中各类注解的作用
1. Junit 测试工具
Junit 是一个 Java 编程语言的单元测试框架
常见的注解有:
- @BeforeClass :表示使用此注解的方法在测试类被调用之前执行,在一个测试类中只能声明此注解一次,此注解对应的方法只能被执行一次。
- @AfterClass :表示使用此注解的方法在测试类被调用结束退出之前执行,在一个测试类中只能声明此注解一次,并且此注解对应的方法只能被执行一次。
- @Before:表示使用此注解的方法在每个@Test调用之前被执行,即一个类中有多少个@Test注解方法,那么@Before注解的方法就会被调用多少次。
- @After:表示使用此注解的方法在每个@Test调用结束之后被执行,即一个类中有多少个@Test注解方法,那么@Before注解的方法就会被调用多少次。
- @Test :表示使用此注解的方法为一个单元测试用例,在一个测试勒种可以多次声明此注解,每个注解为@Test的方法只被执行一次。
Junit测试用例的完整的执行顺序:
- @BeforeClass–>@Before–>@Test–>@After—>@AfterClass
测试验证:
需要创建的类有如下红框标记:
先编写一个实体类Student
package com.zz.domain;public class Student {private int id; //学号private String name; //姓名private String gender; //性别private String birthday; //出生日期private String major; //专业public Student() {}public Student(int id, String name, String gender, String birthday, String major) {this.id = id;this.name = name;this.gender = gender;this.birthday = birthday;this.major = major;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public String getBirthday() {return birthday;}public void setBirthday(String birthday) {this.birthday = birthday;}public String getMajor() {return major;}public void setMajor(String major) {this.major = major;}@Overridepublic String toString() {return "Student{" +"id=" + id +", name='" + name + '\'' +", gender='" + gender + '\'' +", birthday='" + birthday + '\'' +", major='" + major + '\'' +'}';}
}
- 再编写applicationContext.xml文档
<?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"><bean id="s1" class="com.zz.domain.Student"><property name="id" value="001"/><property name="name" value="张一"/><property name="gender" value="男" /><property name="birthday" value="2009-05-18"/><property name="major" value="九阴真经" /></bean><bean id="s2" class="com.zz.domain.Student"><property name="id" value="002"/><property name="name" value="黄二"/><property name="gender" value="男" /><property name="birthday" value="2011-07-08"/><property name="major" value="如来神掌" /></bean>
</beans>
- 编写测试类StudentDomainTest
package com.zz.domain;import org.junit.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class StudentDomainTest {private static ApplicationContext context;//@BeforeClass,测试类的初始化过程,仅仅初始化一次。@BeforeClasspublic static void initContext(){System.out.println("执行了@BeforeClass的initContext()...");context = new ClassPathXmlApplicationContext("applicationContext.xml");}//用来初始化测试用例的,每次测试都执行。@Beforepublic void initTest(){System.out.println("执行了@Before的initTeset()...");}@Afterpublic void afterTest(){System.out.println("执行了@After的afterTeset()...");}//测试用例@Testpublic void testGetStudents1(){//初始化上下文(IOC容器)//ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");System.out.println("执行了@Test的testGetStudents1()...");Student s1 = (Student) context.getBean("s1");System.out.println(s1);}//测试用例@Testpublic void testGetStudents2(){//初始化上下文(IOC容器)//ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");System.out.println("执行了@Test的testGetStudents2()...");Student s2 = (Student) context.getBean("s2");System.out.println(s2);}@AfterClasspublic static void destroy(){System.out.println("执行了@AfterClass的destroy()...");}
}
- 运行结果
2. getBean的五种用法
(1)getBean(String id/name)
id不能重复,只能写一个,并且不能和name重复
name可写多个,并且也不能和id重复
<bean id="s1" class="com.zz.domain.Student">
<bean name="name1,name2,name3" class="com.zz.domain.Student">
需要进行类型转换
Student s1 = (Student) context.getBean("s1");
(2)getBean(Class clazz)
通过类型加载,要求类型不能重复。好处是:无需类型转换
Student s1 = context.getBean(Student.class);
(3)getBean(String id/name,Class clazz);
通过id/name和类型查找,好处是:无需类型转换。
Student s1 = context.getBean("s1", Student.class);
(4)getBean(Class clazz,Object …objs)
Student s1 = context.getBean(Student.class,new Object[]{003,"胡三","女","1999-11-10","降龙十八掌"});
如果第二个参数是带对象数组的,一定是想返回使用对象数组初始化属性的对象。运行结果发现还是之前的对象。
解决方法:通过工厂模式生成对象
工厂类 StudentFactory
package com.zz.factory;
import com.zz.domain.Student;
import java.lang.reflect.Constructor;//使用工厂模式来生成学生。
public class StudentFactory {public static Student getStudentInstance(int sid,String sname,String gender,String birthday,String major) throws Exception{Class clazz = Class.forName("com.zz.domain.Student");//反射出构造方法。Constructor constructor = clazz.getConstructor(int.class,String.class,String.class,String.class,String.class);return (Student)constructor.newInstance(sid,sname,gender,birthday,major);}
}
applicationContext.xml文档
<!--prototype 原型(非单例)--><bean id="s1" factory-method="getStudentInstance" class="com.zz.factory.StudentFactory" scope="prototype"><constructor-arg name="id" value="111"/><constructor-arg name="name" value=""/><constructor-arg name="gender" value=""/><constructor-arg name="birthday" value=""/><constructor-arg name="major" value=""/></bean>
运行结果
(5)getBean(String id/name,Object …objs)
与(4)方法相同,通过工厂方法生成对象,objs 初始化对象时的参数列表
3. 属性的注入方式
在实际项目开发时一般不配置applicationContext.xml,太麻烦,都是使用注解来注入
在applicationContext.xml中只需要开启注解:
<context:component-scan base-package="com.zz"/>
xml配置:简单来说就是配置applicationContext.xml. 里面通过注入对象。
注解配置:类上面添加@Configuration注解,那么这个类作用等同于applicationContext.xml
@Bean 注解的作用等同于
(1)通过property注入
applicationContext.xml文档
<bean id="s2" class="com.zz.domain.Student"><property name="id" value="002"/><property name="name" value="黄二"/><property name="gender" value="男" /><property name="birthday" value="2011-07-08"/><property name="major" value="如来神掌" /></bean>
</beans>
测试类
@Testpublic void testPropertiesInject(){//1.通过property注入Student s1 = (Student) context.getBean("s2");System.out.println(s1); //Student{id=2, name='黄二', gender='男', birthday='2011-07-08', major='如来神掌'}}
(2)通过 constructor-arg 注入,本质是调用构造方法
applicationContext.xml文档
<!--构造方法注入--><bean name="hehe,haha" class="com.zz.domain.Student"><constructor-arg name="id" value="111"/><constructor-arg name="name" value="郭三"/><constructor-arg name="gender" value="男"/><constructor-arg name="birthday" value="1999-09-10"/><constructor-arg name="major" value="九阴真经"/></bean>
测试类
@Testpublic void testPropertiesInject(){//通过构造方法注入Student s1 = (Student) context.getBean("haha");System.out.println(s1); //Student{id=111, name='郭三', gender='男', birthday='1999-09-10', major='九阴真经'}}
(3)通过@Value 注解注入,不推荐这种
开启注解方法:在applicationContext.xml 中添加
<context:component-scan base-package=“com.zz”/>
<!--@Value注解注入--><!--开启注解功能--><context:component-scan base-package="com.zz"/><bean name="hehe,haha" class="com.zz.domain.Student" scope="prototype"></bean>
Student类
在成员变量前都加@value(“xxx”),这样做会造成初始化任何一个Students对象,属性赋值都是一样的,所以不推荐使用。
@Value("777")
private int id; //学号
@Value("周六")
private String name; //姓名
@Value("男")
private String gender; //性别
@Value("1998-02-03")
private String birthday; //出生日期
@Value("吹牛逼")
private String major; //专业
测试类
@Testpublic void testPropertiesInject(){//通过 @Value注入Student s1 = (Student) context.getBean("haha");System.out.println(s1); //Student{id=777, name='周六', gender='男', birthday='1998-02-03', major='吹牛逼'}}
(4)通过@Bean 注入,配合@Configuration 使用
创建一个SpringConfiguration类
package com.zz.config;import com.zz.domain.Student;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;//带@Configuration注解的类等同于applicationContext.xml
@Configuration
public class SpringConfiguration {//在IOC容器中初始化了一个id=haha的对象@Bean("haha")public Student getStudentsBean1(){Student s = new Student(666,"郭九","男","2009-10-10","画画");return s;}@Bean("xixi")public Student getStudentsBean2(){Student s = new Student(200,"陈三","女","2000-10-10","美术");return s;}
}
同样applicationContext.xml中只需要开启注解:
添加 <context:component-scan base-package=“com.zz”/>
测试类
@Testpublic void testPropertiesInject(){//通过 注解注入Student s1 = (Student) context.getBean("xixi"); //改为haha,得到的就是Student{id=666, name='郭九', gender='男', birthday='2009-10-10', major='画画'}System.out.println(s1); //Student{id=200, name='陈三', gender='女', birthday='2000-10-10', major='美术'}}
4. bean的生存范围和加载策略
生存范围:
scope有两个常用属性:singleton(单例)和prototype(原型)。默认情况下为singleton。
singleton:无论这个bean被取多少次,都是同一个对象
<bean id="001" class="com.zz.domain.Student">
prototype:每次bean取的对象不同
<bean id="001" class="com.zz.domain.Student" scope="prototype">
对应的注解的写法:
@Scope("singleton") 或 @Scope("prototype")
加载策略:
在实体类上添加
@Component@Lazy(true/false)
@Lazy(true) 表示懒加载,用到的时候再调用构造方法来实例化bean,不用就不实例化
@Lazy(false) 表示积极加载,默认是false; 不管是否用到,都事先加载出来
5. 自定义属性的注入方式
如实体类People中带有复杂属性Car
创建两个实体类People和Car
package com.zz.domain;public class Person {private String name;private String gender;private int age;private Car car;public Person() {}public Person(String name, String gender, int age, Car car) {this.name = name;this.gender = gender;this.age = age;this.car = car;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Car getCar() {return car;}public void setCar(Car car) {this.car = car;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", gender='" + gender + '\'' +", age=" + age +", car=" + car +'}';}
}
package com.zz.domain;public class Car {private String brand;private String color;private int price;public Car() {}public Car(String brand, String color, int price) {this.brand = brand;this.color = color;this.price = price;}public String getBrand() {return brand;}public void setBrand(String brand) {this.brand = brand;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}public int getPrice() {return price;}public void setPrice(int price) {this.price = price;}@Overridepublic String toString() {return "Car{" +"brand='" + brand + '\'' +", color='" + color + '\'' +", price=" + price +'}';}
}
创建一个注解配置类 SpringConfiguration2
package com.zz.config;import com.zz.domain.Car;
import com.zz.domain.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class SpringConfiguration2 {@Bean("p1")public Person getPerson1(@Autowired Car car){//按类型注入一个Carreturn new Person("张三","男",30,car);}@Bean("car1")public Car getCar1(){return new Car("BMW","黑色",400000);}
}
创建 PersonDomainTest 测试类
package com.zz.domain;import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class PersonDomainTest {private static ApplicationContext context;//@BeforeClass,测试类的初始化过程,仅仅初始化一次。@BeforeClasspublic static void initContext(){System.out.println("执行了initContext..");context = new ClassPathXmlApplicationContext("applicationContext.xml");}@Testpublic void testGetPersonBean(){Person p = (Person) context.getBean("p1");System.out.println(p); //Person{name='张三', gender='男', age=30, car=Car{brand='BMW', color='黑色', price=400000}}}
}
6. Spring中各类注解的作用
@Component:添加在实体类,表示是一个组件
@Repository:添加在接口上,表示是接口
@Controller:添加在控制层上,表示是一个Controller,Controller属于SpringMVC的内容
@Service:添加在服务层上,表示是服务层代码
@Autowire:自动注入,根据类型
@Resource:自动注入,根据名字
@Bean:表示一个bean对象
@Configuration:配置注解
@Scope:生存范围
@Lazy:加载策略
Spring(二)——Junit测试工具、属性的注入方式、注解相关推荐
- spring使用JUnit测试,@Autowired无法注入原因
在测试类上加入配置文件 代码如下 @RunWith(SpringJUnit4ClassRunner.class)// SpringJUnit支持,由此引入Spring-Test框架支持! @Conte ...
- 白盒测试之Junit测试工具的使用
本篇讲解软件测试技术之Junit测试工具的使用.Eclipse中集成了JUnit,不用安装就可以在项目中测试相关的类,并且可以调试测试用例和被测试类,可以非常方便的编写TestCase.(下载ecli ...
- Spring Boot JUnit 测试 Controller
Spring Boot JUnit 测试 Controller Controller层代码如下: @RestController public class HelloController {Logge ...
- java spring注入 静态方法_java相关:spring为类的静态属性实现注入实例方法
java相关:spring为类的静态属性实现注入实例方法 发布于 2020-3-31| 复制链接 在本篇文章里小妖给大家整理的是关于spring为类的静态属性实现注入实例方法,有需要的朋友们可以参考下 ...
- spring整合junit测试
接下来说一下与Junit整合测试,这个整合测试实际上是这样,来一个test,咱们如果要测试很多功能的话,我把很多方法就复制粘贴粘贴,比如我这三个方法都是测试不同的功能,你看我是不是在每一个方法里面,是 ...
- java junit autowired_写Junit测试时用Autowired注入的类实例始终为空怎么解?
踩坑半天多,终于在网上寻觅到了解决方案,特此分享一下. 重要前提:src/main/java下的根包名必须和src/test/main的根包名完全一致,否则就会发生死活不能注入的情况,要继续进行下面的 ...
- 原创:Spring整合junit测试框架(简易教程 基于myeclipse,不需要麻烦的导包)
我用的是myeclipse 10,之前一直想要用junit来测试含有spring注解或动态注入的类方法,可是由于在网上找的相关的jar文件进行测试,老是报这样那样的错误,今天无意中发现myeclips ...
- Junit测试工具使用
Junit是单元测试框架工具,在项目开发中是经常用到的,利用JUnit4进行单元测试非常简单方便,所以熟悉Junit是很有必要的. Junit优点: 安装使用方便 可以同时执行多个测试方法 测试结果直 ...
- 测试面试题集锦(二)| 测试工具篇(附答案)
本文为霍格沃兹测试学院学员学习笔记. 本系列文章总结归纳了一些软件测试工程师常见的面试题,主要来源于个人面试遇到的.网络搜集(完善).工作日常讨论等,分为以下十个部分,供大家参考.如有错误的地方,欢迎 ...
最新文章
- 静态嵌套类(Static Nested Class)和内部类(Inner Class)的不同?
- Happy Number
- 英特尔“包抄”英伟达:oneAPI对标CUDA、为《王者荣耀》云游戏提供GPU
- Java NIO类库Selector机制解析--转
- iOS开发教程:Storyboard全解析-第二部分
- SAP Spartacus autofocus Directive的失败的单元测试 - 2021年1月13日 1.1
- QT中信号和信号槽详解
- ​【文末有福利】《信条》中的物理学-时间机器存在吗?
- 江苏省计算机学会博士论文,江苏学会网 欢迎您成为江苏省计算机学会会员
- 【Elasticsearch】关于 Analyzers 的一切,第一部分
- git commit之后后面的操作步骤
- AutoLayout的三种设置方式之——NSLayoutConstraint代码篇
- IIS配置aspnet常见为题
- 简单使用idea Spring Boot搭建项目
- Django:学习笔记(4)——请求与响应
- 微信公众平台与微信公众平台的区别与联系
- 字符串intern()方法详解
- 语音识别之wave文件(*.wav)格式、PCM数据格式介绍
- 曙光“城市大数据平台”冲破数据孤岛、创造数据价值
- 利用Python绘制小狗小猫
热门文章
- ICCV 2017 EAST:《Learning Policies for Adaptive Tracking with Deep Feature Cascades》论文笔记
- CVPR 2018 目标跟踪相关论文
- php 根据键名分类求和,二维数组根据键值相加
- spark ui的访问地址_Spark篇之HA集群搭建
- java环境变量配置(win7)
- Android Studio下项目构建的Gradle配置及打包应用变体
- 小米手机与魅族的PK战结果 说明了什么
- Adaboost 2
- SqlDataAdapter的使用注意事项
- C#比较数组内元素相等-冒泡