Spring-02-注入和注解方式操作回顾:任务目标一. 依赖注入1. set方法注入1.1 基本类型值注入使用value1.2 引入类型值注入ref2.构造函数注入2.1 单个有参构造方法注入2.2. index属性:按参数索引注入2.3. type属性:按参数类型注入3. p名称空间注入4. spel注入5. 复杂类型注入二.使用注解1. 准备工作2. 使用注解2.1 引入Context的约束2.2 配置注解扫描2.3 使用注解3. 其他注解3.1 类头部可用的注解3.2 类头部可用的注解3.3 注入属性value值3.4 自动装配3.5 @Qualifier3.6 @Resource3.7 初始化和销毁方法三. Spring整合JUnit测试复习作业面试题
1. Spring的简介 2. IOC和DI的简介和关系 3. Spring对象创建过程和配置
1. 依赖注入详解 2. 使用注解的方式实现依赖注入 3. Spring中使用JUnit测试
1. 掌握依赖注入的各种配置和属性 2. 掌握注解的方式实现依赖注入 3. 掌握在Spring中使用JUnit测试
测试类:Person.java
创建配置文件:applicationContext-injection.xml
创建测试代码:InjectionTest.java
配置:
xxxxxxxxxx <!-- value值为基本类型 --> <bean name="person" class="com.itqf.spring.bean.Person" > <property name="name" value="jeck" /> <property name="age" value="11"/> </bean>测试代码:
x public void test1(){ //TODO 测试基本数据类型注入数据 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-injection.xml"); Person person = context.getBean("person", Person.class); System.out.println("person = " + person); //输出结果:------------> Person.Person // person = Person{name='jeck', age=11} }创建 Car.java:
xxxxxxxxxxpublic class Car { private String name; private String color; public Car() { super(); System.out.println("Car的空参构造方法"); } //getter、setter、toString}修改Person.java,在Person中引入Car:
xxxxxxxxxxpublic class Person { private String name; private Integer age; private Car car; //构造方法 getter setter toString方法 }配置:利用ref属性给 person的car属性赋值
xxxxxxxxxx <bean name="person1" class="com.itqf.spring.bean.Person"> <property name="name" value="helen"></property> <property name="age" value="18"></property> <property name="car" ref="car"></property> </bean> <bean name="car" class="com.itqf.spring.bean.Car"> <property name="name" value="MINI"></property> <property name="color" value="灰色" ></property> </bean>测试: 使用之前测试用例即可!
在Person中创建有参构造函数:
xxxxxxxxxx public Person(String name , Car car){ this.name = name; this.car = car; System.out.println("Person的有参构造方法:"+name+car); }配置:
xxxxxxxxxx<bean name="person" class="com.itqf.spring.bean.Person"> <constructor-arg name="name" value="rose"/> <constructor-arg name="car" ref="car"/> </bean> <!-- 构造函数car时候引入 --> <bean name="car" class="com.itqf.spring.bean.Car" > <property name="name" value="mime"/> <property name="color" value="白色"/> </bean>测试:
xxxxxxxxxx public void test2(){ //TODO 测试参构造方法 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-injection.xml"); Person person = context.getBean("person", Person.class); System.out.println(person); //结果:调用有参数构造方法,输出 }参数名一致,但位置不一致时,使用 index
例如以下两个构造函数(第二个是新添加):
xxxxxxxxxx public Person(String name, Car car) { super(); System.out.println("Person(String name, Car car)"); this.name = name; this.car = car; } public Person(Car car, String name) { super(); System.out.println("Person(Car car, String name)"); this.name = name; this.car = car; }配置:使用 index 确定调用哪个构造函数
xxxxxxxxxx <bean name="person2" class="com.itqf.spring.bean.Person"> <constructor-arg name="name" value="helen" index="0"></constructor-arg> <constructor-arg name="car" ref="car" index="1"></constructor-arg> </bean>测试:
重新执行第一步的测试用例,执行结果调用了第一个构造函数
参数名和位置一致,但类型不一致时,使用type
例如以下两个构造函数(第二个是新添加):
xxxxxxxxxx public Person(Car car, String name) { super(); System.out.println("Person(Car car, String name)"); this.name = name; this.car = car; } public Person(Car car, Integer name) { super(); System.out.println("Person(Car car, Integer name)"); this.name = name + ""; this.car = car; }配置:使用type指定参数的类型
xxxxxxxxxx <bean name="person2" class="com.itqf.spring.bean.Person"> <constructor-arg name="name" value="988" type="java.lang.Integer"></constructor-arg> <constructor-arg name="car" ref="car" ></constructor-arg> </bean>测试:
重新执行前面的测试用例,执行结果调用了第二个构造函数
导入p名称空间:
使用p:属性名 完成注入,走set方法
配置:
xxxxxxxxxx//1.第一步配置文件中 添加命名空间p xmlns:p="http://www.springframework.org/schema/p"<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> //使用 p命称空间进行赋值 <bean name="person" class="com.itqf.spring.bean.Person" p:name="人名" p:age="11" p:car-ref="car"> </bean> <bean name="car" class="com.itqf.spring.bean.Car" > <property name="name" value="mime" /> <property name="color" value="白色"/> </bean> 测试:
xxxxxxxxxxpublic void test2(){ //TODO 测试p命名空间注入 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-injection.xml"); Person person = context.getBean("person", Person.class); System.out.println(person); }spring Expression Language:spring表达式语言
配置:
xxxxxxxxxx <bean name="car" class="com.itqf.spring.bean.Car" > <property name="name" value="mime" /> <property name="color" value="白色"/> </bean> <!--利用spel引入car的属性 --> <bean name="person1" class="com.itqf.spring.bean.Person" p:car-ref="car"> <property name="name" value="#{car.name}"/> <property name="age" value="#{person.age}"/> </bean>测试
xxxxxxxxxxpublic void test3(){ //TODO 测试spel注入 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-injection.xml"); Person person = context.getBean("person1", Person.class); System.out.println(person); }创建配置文件:application-collection.xml
创建测试代码:CollectionTest.java
创建测试实体类:TestCollection
创建TestCollection:
xxxxxxxxxx/** * 练习:arr list map properties的注入 */public class TestCollection { private Object [] arrs; private List<Object> list; private Map<String,Object> map; private Properties properties; public Object[] getArrs() { return arrs; } public void setArrs(Object[] arrs) { this.arrs = arrs; } public List<Object> getList() { return list; } public void setList(List<Object> list) { this.list = list; } public Map<String, Object> getMap() { return map; } public void setMap(Map<String, Object> map) { this.map = map; } public Properties getProperties() { return properties; } public void setProperties(Properties properties) { this.properties = properties; } public String toString() { return "TestCollection{" + "arrs=" + Arrays.toString(arrs) + ", list=" + list + ", map=" + map + ", properties=" + properties + '}'; }}配置:
xxxxxxxxxx<?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 name="car" class="com.itqf.spring.bean.Car"> <property name="name" value="保时捷"/> <property name="color" value="红色" /> </bean> <bean name="testColl" class="com.itqf.spring.bean.TestCollection"> <!-- 数组变量注入 --> <property name="arrs"> <list> <value>数组1</value> <!--引入其他类型--> <ref bean="car"/> </list> </property> <!-- 集合变量赋值--> <property name="list"> <list> <value>集合1</value> <!--集合变量内部包含集合--> <list> <value>集合中的集合1</value> <value>集合中的集合2</value> <value>集合中的集合3</value> </list> <ref bean="car" /> </list> </property> <!--map赋值 --> <property name="map"> <map> <entry key="car" value-ref="car" /> <entry key="name" value="保时捷" /> <entry key="age" value="11"/> </map> </property> <!-- properties赋值 --> <property name="properties"> <props> <prop key="name">pro1</prop> <prop key="age">111</prop> </props> </property> </bean></beans>测试:
xxxxxxxxxx public void test4(){ //TODO 复杂类型注入练习 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-collection.xml"); TestCollection textColl = context.getBean("testColl", TestCollection.class); System.out.println("testColl = " + textColl); }使用注解的方式完成IOC
参考文件位置:spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html\xsd-configuration.html 40.2.8 the context schema
配置:
xxxxxxxxxx <!--较之前多了 xmlns:context --><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"> <!-- bean definitions here --> </beans>在applicationContext.xml中配置:
指定扫描 包 下所有类中的注解,扫描包时,会扫描包所有的子孙包.
xxxxxxxxxx <!--较之前多了 xmlns:context --><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"> <!-- bean definitions here --> <!--扫描包设置--> <context:component-scan base-package="com.itqf.spring.bean"> </context:component-scan></beans>在Person类的头部添加如下注解
xxxxxxxxxx/** * @Component(person) == <bean name="person" class="com.itqf.spring.bean.Person" /> */("person")public class Person { private String name; private Integer age; private Car car; public Person(){ System.out.println("无参数构造方法!"); } //getter,setter,toString} 测试:
xxxxxxxxxx public void test1(){ //TODO 测试注解入门 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Person person = context.getBean("person", Person.class); System.out.println("person = " + person); }介绍其他常用注解,测试方式同前
xxxxxxxxxx("person") // service层("person") // controller层("person") // dao层指定对象作用域
xxxxxxxxxx(scopeName="singleton")(scopeName="prototype")1.设置成员变量上:通过反射给变量赋值
xxxxxxxxxx("name值")private String name;@Value("name值") 等同于 @Value(value="name值")
2.加在set方法上:通过set方法赋值
xxxxxxxxxx("tom")public void setName(String name){ this.name = name;} 使用 @Autowired 自动装配对象类型的属性: 下面的Person中的Car使用了自动装配
xxxxxxxxxx//将Car定义成接口public interface Car { void log();}//Baoma实现Carpublic class Baoma implements Car { public void log() { System.out.println("宝马"); }}//XianDai实现Carpublic class XianDai implements Car { public void log() { System.out.println("现代"); }}装配类:
xxxxxxxxxx(scopeName = "prototype")("person")public class Person { ("name值") private String name; private Integer age; private Car car; //自动装配 可以选择Car,如果Car是接口,找Car的实现类!注意: 以上操作会出现一个问题,如果Car是接口,且Car只有一个实现类,那么@Autowired会自动将实现类装配给Person的car变量上,但是如果Car是接口,并且有两个以上实现类,那么自动装配就会报错,无法选择由哪个实现类赋值.所以需要配合另一个注释@Qualifier("bean name"), 这个属性可以将@Autowired按类型赋值改成按bean名字赋值.
@Qualifier()注解告诉spring容器自动装配哪个名称的对象。 xxxxxxxxxx(scopeName = "prototype")("person")public class Person { ("name值") private String name; private Integer age; ("baoma") //指定实现类 private Car car; //自动装配 可以选择Car,如果Car是接口,找Car的实现类!@Resource 是java的注释,但是Spring框架支持,@Resource指定注入哪个名称的对象
@Resource("name") == @Autowired + @Qualifier("name")
xxxxxxxxxx("baoma") private Car car;初始化和销毁方法等同于配置文件添加的init-method和destroy-method功能,
例:Person类中init方法和destroy方法添加如下注解:
xxxxxxxxxx public void init(){ System.out.println("初始化方法"); } public void destroy(){ System.out.println("销毁方法"); }spring整合junit,为我们提供了方便的测试方式
1、导包:在spring-02-annotation项目中再加入如下包
spring-test-4.2.8.jar
2、创建测试类
xxxxxxxxxx//创建容器(SpringJUnit4ClassRunner.class)//指定创建容器时使用哪个配置文件("classpath:applicationContext.xml")public class RunWithTest { //将名为user的对象注入到u变量中 (name="person") private Person p; public void testCreatePerson(){ System.out.println(p); }}1. Spring的基本配置 2. 代码实现Spring创建对象过程
1. 创建汽车类(Car)和引擎接口(Engine) 2. 创建两个引擎的实现类V6Engine和V8Engine 3. 使用依赖注入的方式显示V6的汽车和V8的汽车奔跑(running)的效果 4. 使用BeanFactory和ApplicationContext分别加载以上的类 5. 使用不同的生命周期创建上面的类并使用JUnit测试不同之处 6. 使用注解的方式再实现一次
1. 在Spring中如何注入基本数据类型 2. @Component注解的作用 3. @Resource注解和@Autowired注解的作用和区别 4. Spring如何集成JUnit