一、Spring IOC、DI 解释
Spring Ioc容器(ApplicationContext)负责创建Bean,并通过容器将这些创建的Bean注入到需要他们的消费者Bean中。Spring提供使用Xml、注解java配置的方式创建和注入,容器解析这些配置信息进行Bean的初始化,配置和依赖管理。
DI(依赖注入),依赖即以组合形式定义其他类型的对象定义为本类的成员变量(对象初始化时依赖于成员变量的初始化),而依赖注入即初始化成员变量,spring依赖注入即为spring在构建对象时对对象的变量进行初始化,即当定义一个对象时,由spring控制对象的创建和初始化。
二、测试用例User.java和Grade.java
---Grade.java
package com.jty.testSpring;
public class Grade {
private String schoolName;//学校名
private String gradeName;//年级名
public Grade() {
super();
}
public Grade(String schoolName, String gradeName) {
super();
this.schoolName = schoolName;
this.gradeName = gradeName;
}
public String getSchoolName() {
return schoolName;
}
public void setSchoolName(String schoolName) {
this.schoolName = schoolName;
}
public String getGradeName() {
return gradeName;
}
public void setGradeName(String gradeName) {
this.gradeName = gradeName;
}
@Override
public String toString() {
return "Grade [schoolName=" + schoolName + ", gradeName=" + gradeName + "]";
}
}
---User.java
package com.jty.testSpring;
public class Student {
private String name;//姓名
private int ages;//年龄
private String address;//地址
private double cost;//零花钱
private Grade grade;
public Student() {
super();
System.out.println("=========调用默认构造器============");
this.name="默认构造器";
this.ages=20;
this.address="江苏省南京市";
this.cost=20.00;
this.grade=new Grade("第三中学","三年级");
}
public Student(String name, Integer ages, String address, Double cost, Grade grade) {
super();
System.out.println("=========调用带参构造器============");
this.name = name;
this.ages = ages;
this.address = address;
this.cost = cost;
this.grade = grade;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAges() {
return ages;
}
public void setAges(int ages) {
this.ages = ages;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public double getCost() {
return cost;
}
public void setCost(double cost) {
this.cost = cost;
}
public Grade getGrade() {
return grade;
}
public void setGrade(Grade grade) {
this.grade = grade;
}
@Override
public String toString() {
return "Student [name=" + name + ", ages=" + ages + ", address=" + address + ", cost=" + cost + ", grade="
+ grade + "]";
}
}
三、构造器注入
(1)默认构造器
注:提供默认构造器
---applicationContext.xml
<bean id="student1" class="com.jty.testSpring.Student">
</bean>
---TestStudent.java
package com.jty.testSpring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestStudent
{
public static void main(String []agrs) {
//获取ioc容器
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
Student student1=applicationContext.getBean(Student.class,"student1");
System.out.println("生成学生用户:"+student1);
}
}
输出:
=调用默认构造器====
生成用户:Student [name=默认构造器, ages=20, address=江苏省南京市, cost=20.0, grade=Grade [schoolName=第三中学, gradeName=三年级]]
(2)显示使用构造器注入
注:必须提供带参构造器,type属性可省略,且只能使用包装类,可使用index-value或type-value属性代替name-value进行初始化,序号从0开始
---applicationContext.xml
---TestStudent.java
package com.jty.testSpring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestStudent
{
public static void main(String []agrs) {
//获取ioc容器
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
Student student2=applicationContext.getBean(Student.class,"student2");
System.out.println("生成学生用户:"+student2);
}
}
输出:
=调用带参构造器====
生成学生用户:Student [name=带参数构造器, ages=21, address=江苏省南京市, cost=20.0, grade=Grade [schoolName=第四中学, gradeName=二年级]]
四、Setter注入
注:必须编写setter方法
---applicationContext.xml
<bean id="grade" class="com.jty.testSpring.Grade">
<constructor-arg name="schoolName" value="第四中学" type="java.lang.String"></constructor-arg>
<constructor-arg name="gradeName" value="二年级" type="java.lang.String"></constructor-arg>
</bean>
<bean id="student3" class="com.jty.testSpring.Student">
<property name="name" value="Setter"></property>
<property name="ages" value="21"></property>
<property name="address" value="江苏省南京市"></property>
<property name="cost" value="20.00"></property>
<property name="grade" ref="grade"></property>
</bean>
---TestStudent.java
package com.jty.testSpring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestStudent
{
public static void main(String []agrs) {
//获取ioc容器
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
Student student3=applicationContext.getBean(Student.class,"student3");
System.out.println("生成学生用户:"+student3);
}
}
输出:
=调用默认构造器====
生成学生用户:Student [name=Setter, ages=21, address=江苏省南京市, cost=20.0, grade=Grade [schoolName=第四中学, gradeName=二年级]]
注:创建Student对象实例时调用默认构造函数,之后调用setter方法初始化对象
五、p命名空间
注:在使用p命名空间注入之前必须先引入p命名空间约束
---applicationContext.xml
<bean id="grade" class="com.jty.testSpring.Grade">
<constructor-arg name="schoolName" value="第四中学" type="java.lang.String"></constructor-arg>
<constructor-arg name="gradeName" value="二年级" type="java.lang.String"></constructor-arg>
</bean>
<bean id="student4" class="com.jty.testSpring.Student"
p:name="p命名"
p:ages="30"
p:address="江苏省南京市"
p:cost="30.00"
p:grade-ref="grade">
</bean>
---TestStudent.java
package com.jty.testSpring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestStudent
{
public static void main(String []agrs) {
//获取ioc容器
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
Student student4=applicationContext.getBean(Student.class,"student4");
System.out.println("生成学生用户:"+student4);
}
}
输出:
=调用默认构造器====
生成学生用户:Student [name=p命名, ages=30, address=江苏省南京市, cost=30.0, grade=Grade [schoolName=第四中学, gradeName=二年级]]
六、基于注解的注入
注:必须引入spring-context名称空间,使用类路径扫描和托管组件
注解释义对照在文末
---applicationContext.xml
<context:component-scan base-package="com.jty.testSpring"></context:component-scan>
---Grade.java
package com.jty.testSpring;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component("grade")
public class Grade {
@Value("第五中学")
private String schoolName;//学校名
@Value("一年级")
private String gradeName;//年级名
public Grade() {
super();
}
public Grade(String schoolName, String gradeName) {
super();
this.schoolName = schoolName;
this.gradeName = gradeName;
}
/*getter、setter、toString略*/
}
---Student.java
package com.jty.testSpring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component("student5")
public class Student {
@Value("基于注解")
private String name;//姓名
@Value("40")
private int ages;//年龄
@Value("贵州省贵阳市")
private String address;//地址
@Value("50.00")
private double cost;//零花钱
@Autowired
@Qualifier("grade")
private Grade grade;
public Student() {
super();
System.out.println("=调用默认构造器");
this.name="用户1";
this.ages=20;
this.address="江苏省南京市";
this.cost=20.00;
this.grade=new Grade("第三中学","三年级");
}
public Student(String name, Integer ages, String address, Double cost, Grade grade) {
super();
System.out.println("=调用带参构造器========");
this.name = name;
this.ages = ages;
this.address = address;
this.cost = cost;
this.grade = grade;
}
/getter、setter、toString略/
}
---TestStudent.java
package com.jty.testSpring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestStudent
{
public static void main(String []agrs) {
//获取ioc容器
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
Student student5=applicationContext.getBean(Student.class,"student5");
System.out.println("生成学生用户:"+student5);
}
}
输出:
=调用默认构造器====
生成学生用户:Student [name=基于注解, ages=40, address=贵州省贵阳市, cost=50.0, grade=Grade [schoolName=第五中学, gradeName=一年级]]
七、集合注入
---MyCollection.java
package com.jty.testSpring;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class MyCollection {
private String[] array;
private List
private Set
private Map<String,String> map;
private Properties pros;
public MyCollection() {
array=new String[5];
list=new ArrayList<String>();
set=new HashSet<String>();
map=new HashMap<String, String>();
pros=new Properties();
}
public String[] getArray() {
return array;
}
public void setArray(String[] array) {
this.array = array;
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
public Set<String> getSet() {
return set;
}
public void setSet(Set<String> set) {
this.set = set;
}
public Map<String, String> getMap() {
return map;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public Properties getPros() {
return pros;
}
public void setPros(Properties pros) {
this.pros = pros;
}
@Override
public String toString() {
return "MyCollection [\n array=" + Arrays.toString(array) + ",\n list=" + list + ",\n set=" + set + ",\n map=" + map + ",\n pros=" + pros + "]";
}
}
---applicationContext.xml
---TestMyCollection.java
package com.jty.testSpring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestMyCollection {
public static void main(String[] args) {
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
MyCollection mycollection=applicationContext.getBean(MyCollection.class,"myCollection");
System.out.println(mycollection);
}
}
输出:
MyCollection [
array=["array 1", "array 2", "array 3", "array 4", "array 5"],
list=[list 1, list 2, list 3, list 4, list 5],
set=[set 1, set 2, set 3, set 4, set 5],
map={key1=map1, key2=map2, key3=map3},
pros={pros1=prop 1, pros3=prop 3, pros2=prop 2}]
总结Summary
使用哪一种注入方式,必须满足相应的前提
构造器注入-提供默认构造器
setter注入-提供setter方法
p命名空间-引入p命名空间
注解注入-引入context命名空间扫描类路径
type属性可省略,且只能使用包装类
普通值使用 value属性,引用值使用ref属性
注解
释义
@Component
@Component("beanId")
@Repository("beanId")//dao层
@Component("beanId")
@Service("beanId")//service层
@Component("beanId")
@Controller("beanId")//视图控制层
@Component("beanId")
@value("初始化值")
@Autowired
引用值按类型自动注入
@Autowired
@ Qualifier("引用变量名")
@Resource("引用变量名")//需要导入 javax.annotation.Resource