使用注解配置spring及junit4整合spring
使用注解配置spring
导包4(beans,context,core,expression)+2(hamcreate-core-1.3,junit-4.1)+1(spring-aop)
- 为主配置文件引入新的命名空间(约束,除开spring beans 还需要 spring context)
- 开启使用注解代替配置文件
- 在类中使用注解完成配置
- 将对象注册到容器中
- 修改对象的作用范围
- 值类型注入
- 引用类型注入
- 初始化和销毁方法
代码模块
-
User
package com.example.bean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
/**
* @Component("user")将User bean让扫描组件可扫描到,并取名为user
* 相当于<bean name="user" class="com/example/bean/User"></bean>
* 注入到扫描组件扫描@Component
* 后又引进了三个注解以作区分,其本质上没有任何区别
* @Service service层
* @Controller web层
* @Repository dao层
*/
@Component("user")
/**
* @Scope(scopeName = "prototype")作用范围,scope默认为singleton单例,这里设置的为原型,也就是多例
*/
/**
* @Value("杨千嬅")赋值,相当于<bean value=""></bean>
*/
//@Scope(scopeName = "prototype")
@Scope(scopeName = "singleton")
public class User {
/**
* 矛盾点:在日常工作中多数人都是直接在属性上赋值,而不是在set方法上赋值。其两者间效果是一致的。看公司要求或个人习惯使用。
* @Value赋值有两种赋值,除了直接在属性上赋值也可以在,这个本质是通过反射的filed赋值
* 其坏处是加在属性值上,破坏了面向对象中的封装思想,这里是直接操作私有化属性值。而不是通过set,get方法去访问它
*
* @Value("吴俊")
* public void setName(String name) {
* this.name = name;
* }
* 上赋值,这个本质是通过set方法赋值
* 在set方法上赋值推荐使用
*/
@Value("杨千嬅")
private String name;
/**
* @Value("18")==@Value(Value="18")
* 1.自定义注解只有一个属性时,且属性名为value时,赋值时value可省略。
*/
@Value("18")
private Integer age;
//给Car对象赋值时,需要先将Car对象注册到扫描组件中供其扫描@Component("car")
/**
*
* @Autowired自动装配,只需去car class中给其私有对象赋值即可
* 引用类型赋值,自动装撇是根据类型查找的,当你car对象有多个时会发生什么???
* 测试,在spring配置文件中新增一个car2去测试
* 问题发生了,如果匹配了多个类型一致的对象,将无法选择具体注入哪一个对象
* 解决办法使用注解@Qualifier,告诉spring自动装配那个名称的对象
* 再查找
*
*/
//@Autowired
//自动装配,找名为car2的车
//@Qualifier("car2")
/**
* @Autowired根据类型查找,当你查找的值有多个相同类型时,将无法确定查找哪个
* 需要和@Qualifier("car2")指定名称配套使用,确定查找值
* 更优解使用@Resource("car2")注解,手动注入,根据名称去查找,推荐
*/
@Resource(name="car2")
private Car car;
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", car=" + car +
'}';
}
/**
* @PostConstruct直译为在构造之后
* 在对象被创建之后调用,相当于init -method
*/
@PostConstruct
public void init(){
System.out.println("这是初始化方法");
}
/**
* @PreDestroy直译为在对象销毁前
* 在对象销毁前被调用,相当于destory -method
* 这里需要注意的是调用销毁方法作用域需要为单例singleton,而不是原型
* 原型每创建一个对象就会new一个新的对象出来,作用域为多例时,会执行两个初始化方法,而不会进入销毁方法
*/
@PreDestroy
public void destory(){
System.out.println("这是销毁方法");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
}
-
Car
package com.example.bean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component("car")
public class Car {
@Value("卡迪拉克")
private String name;
@Value("橙色")
private String color;
public Car(){
}
public Car(String name, String color) {
this.name = name;
this.color = color;
}
@Override
public String toString() {
return "Car{" +
"name='" + name + '\'' +
", color='" + color + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
-
Demo
package com.example.annotation;
import com.example.bean.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Demo {
@Test
public void fun(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) ac.getBean("user");//这个的user为你的组件名称
User user2= (User) ac.getBean("user");
//测试原型
System.out.println(user==user2);
//打印User
System.out.println(user);
}
//测试初始化和销毁方法
@Test
public void fun1(){
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) ac.getBean("user");//这个的user为你的组件名称
User user2= (User) ac.getBean("user");
//单例 true
System.out.println(user==user2);
//打印User
System.out.println(user);
ac.close();
}
}
-
appliactionContext.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"
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 https://www.springframework.org/schema/context/spring-context.xsd">
<!--引用注解前要先添加context.xsd头文件-->
<!--开启注解 <context:component-scan base-package="com.example.bean"></context:component-scan>
扫描组件:扫描基础包com.example.bean,扫描bean下所有类的注解。可以扩大扫描的范围com.example,此时范围为全项目下。
注意:在扫描包时,会扫描包下所有的子孙包
-->
<context:component-scan base-package="com.example.bean"></context:component-scan>
<bean name="car2" class="com.example.bean.Car">
<property name="name" value="自行车"></property>
<property name="color" value="黑色"></property>
</bean>
</beans>
Junit4整合Spring
junit4整合spring步骤
1.先导入spring test包
2.使用@RunWith创建容器.SpringJUnit4ClassRunner.class。这种写法是为了让测试在Spring容器环境下执行。
3.使用@ContextConfiguration指定创建容器时使用的哪个配置文件
4.获取对象 private User u;
-
Demo2
package com.example.jtest;
import com.example.bean.Car;
import com.example.bean.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
/**
* @RunWith()
* 通过这个方法来指定一个类,然后它会调用这个类的指定方法,来创建当前的测试环境
* @RunWith(SpringJUnit4ClassRunner)这个注解的作用就是帮我们创建容器
* @ContextConfiguration("classpath:applicationContext.xml")指定创建容器时使用的是哪个配置文件
* 这两个注解@RunWith必须配套@ContextConfiguration使用,@RunWith创建容器前必须要先读取到指定容器的配置文件
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo2 {
/**
* junit4整合spring
* 往常是每写一个单元测试,就需要拿到其配置文件和其类对象,步骤重复,代码量冗余。类似Demo里的
*/
/**
* junit4整合spring步骤
* 1.先导入spring test包
* 2.使用@RunWith创建容器.SpringJUnit4ClassRunner.class。这种写法是为了让测试在Spring容器环境下执行。
* 3.使用@ContextConfiguration指定创建容器时使用的哪个配置文件
* 4.获取对象 private User u;
*
*/
//获取对象,将名为user的对象注入到u变量中
@Resource(name="user")
private User u;
//将配置文件中的car2注入到c变量中
@Resource(name = "car2")
private Car c;
//同类时一样,根据名称获取,这次获取的是Car对象中的局部变量值
@Resource(name = "car")
private Car c2;
@Test
public void run(){
System.out.println(u);
System.out.println(c);
System.out.println(c2);
}
}


浙公网安备 33010602011771号