DI:Dependency Injection(依赖注入),通俗的讲就是一种通过xml配置文件,为交给sping容器的对象初始化参数。又称做控制反转:Inversion of Control(IoC)
依赖注入主要分为四种形式:
|-:基于构造方法的依赖注入
|-:基于setter方法的依赖注入
|-:基于工厂的注入
|-:基于泛型的注入
基于构造方法的依赖注入又可以分为以下几种:
·复杂数据类型:
·简单数据类型:
|- 基于属性类型(type)
|-基于索引(index)
|-基于参数名称(name)
复杂数据类型实例
package com.fuwh.spring; /*
* POJO类
*/
public class Clazz { private String name;
private int grade;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getGrade() {
return grade;
}
public void setGrade(int grade) {
this.grade = grade;
} }
package com.fuwh.spring;
/*
* POJO类
*/
public class Lesson { private String name;
private int score;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
} }
package com.fuwh.spring; public class Student { private Clazz clazz;
private Lesson lesson; public Student(Clazz clazz, Lesson lesson) {
this.clazz = clazz;
this.lesson = lesson;
} @Override
public String toString() {
return "Student [clazz=" + clazz.getGrade()+clazz.getName() + ", lesson=" + lesson.getName()+","+lesson.getScore() + "学分]";
} } <?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="student" class="com.fuwh.spring.Student" lazy-init="default">
<constructor-arg ref="clazz"/>
<constructor-arg ref="lesson"/>
</bean> <bean id="clazz" class="com.fuwh.spring.Clazz">
<property name="name" value="信本"/>
<property name="grade" value="08"/>
</bean>
<bean id="lesson" class="com.fuwh.spring.Lesson">
<property name="name" value="java"/>
<property name="score" value="4"/>
</bean>
</beans> package com.fuwh.spring; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Spring01 { public static void main(String[] args) {
/*
* 测试类
*/
ApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml");
System.out.println(ac.getBean("student",Student.class));
}
}
基于属性类型(type) 实例:
package com.fuwh.spring;
/*
* POJO类
*/
public class Clazz { private String name;
private int grade; public Clazz(String name, int grade) {
super();
this.name = name;
this.grade = grade;
}
@Override
public String toString() {
return "Student [name=" + name + ", grade=" + grade + "]";
} }
<?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"> <!-- spring配置文件 -->
<bean id="clazz" class="com.fuwh.spring.Clazz" lazy-init="default">
<constructor-arg type="String" value="信息与计算科学"/>
<constructor-arg type="int" value="08"/>
</bean>
</beans>
package com.fuwh.spring; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Spring01 { public static void main(String[] args) {
/*
* 测试类
*/
//ApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml");
//ApplicationContext ac=new ClassPathXmlApplicationContext(new String[]{"beanStudent.xml","beanClazz.xml"});
//ApplicationContext ac=new ClassPathXmlApplicationContext("beanStudent.xml");
//System.out.println(ac.getBean("student"));
ApplicationContext ac=new ClassPathXmlApplicationContext("beanClazz.xml");
System.out.println(ac.getBean("clazz",Clazz.class));
}
}
基于索引(index)实例:
※需要注意的是,索引是从“0”开始
<?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"> <!-- spring配置文件 -->
<bean id="clazz" class="com.fuwh.spring.Clazz" lazy-init="default">
<constructor-arg index="0" value="信息与计算科学"/>
<constructor-arg index="1" value="08"/>
</bean>
</beans>
基于参数名称(name)实例:
<?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"> <!-- spring配置文件 -->
<bean id="clazz" class="com.fuwh.spring.Clazz" lazy-init="default">
<constructor-arg name="name" value="信息与计算科学"/>
<constructor-arg name="grade" index="1" value="08"/>
</bean>
</beans>
基于setter方法的依赖注入
package com.fuwh.spring; /*
* POJO类
*/
public class Lesson { private String name;
private int score; public void setName(String name) {
System.out.println("name parameter is injected");
this.name = name;
} public void setScore(int score) {
System.out.println("score parameter is injected");
this.score = score;
} @Override
public String toString() {
return "Lesson [name=" + name + ", score=" + score + "学分]";
} }
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- spring配置文件 -->
<bean id="lesson" class="com.fuwh.spring.Lesson" lazy-init="default"
p:name="php"
p:score="2"/>
</beans>
package com.fuwh.spring; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Spring01 { public static void main(String[] args) {
/*
* 测试类
*/
ApplicationContext ac=new ClassPathXmlApplicationContext("beanLesson.xml");
System.out.println(ac.getBean("lesson",Lesson.class));
}
}
在注入的时候,使用以上两种方式都是可以的,但是在以下一种情况下,只能使用setter的方式注入
Class A的构造方法中需要Class B的实例, Class B的构造方法中又需要Class A的实例,
这时候就会报BeanCurrentlyInCreationException的exception.
级联属性注入
package com.fuwh.test; public class People { public int id;
public String name;
public int age; public Dog dog=new Dog(); 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 int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public Dog getDog() {
return dog;
} public void setDog(Dog dog) {
this.dog = dog;
} @Override
public String toString() {
return "People [id=" + id + ", name=" + name + ", age=" + age + ", dog=" + dog + "]";
} }
package com.fuwh.test; public class Dog { public int id;
public String name;
public int age;
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 int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Dog [id=" + id + ", name=" + name + ", age=" + age + "]";
} }
<?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="people" class="com.fuwh.test.People">
<property name="id" value="1"></property>
<property name="name" value="laofu"></property>
<property name="age" value="27"></property> <!-- dog就是属于级联的初始化 -->
<property name="dog.id" value="12"></property>
<property name="dog.name" value="wangcai"></property>
<property name="dog.age" value="11"></property>
</bean> </beans>
最后,使用junit4进行测试
package com.fuwh.test; import org.junit.Before;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { private ApplicationContext ac; @Before
public void setUp() throws Exception {
ac=new ClassPathXmlApplicationContext("beans.xml");
} @org.junit.Test
public void test() {
People people =(People)ac.getBean("people");
System.out.println(people);
} }
注入集合变量
List
package com.fuwh.test; import java.util.ArrayList;
import java.util.List; public class People { public int id;
public String name;
public int age; public List<String> nameList=new ArrayList<String>(); public List<String> getNameList() {
return nameList;
} public void setNameList(List<String> nameList) {
this.nameList = nameList;
} 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 int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} @Override
public String toString() {
return "People [id=" + id + ", name=" + name + ", age=" + age + ", nameList=" + nameList + "]";
} }
<?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="people" class="com.fuwh.test.People">
<property name="id" value="1"></property>
<property name="name" value="laofu"></property>
<property name="age" value="27"></property> <property name="nameList">
<list>
<value>唱歌</value>
<value>跳舞</value>
<value>编程</value>
</list>
</property>
</bean> </beans>
package com.fuwh.test; import org.junit.Before;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { private ApplicationContext ac; @Before
public void setUp() throws Exception {
ac=new ClassPathXmlApplicationContext("beans.xml");
} @org.junit.Test
public void test() {
People people =(People)ac.getBean("people"); System.out.println(people);
} }
map
package com.fuwh.test; import java.util.HashMap;
import java.util.Map; public class People { public int id;
public String name;
public int age; public Map<String,String> nameMap=new HashMap<String,String>(); public Map<String, String> getNameMap() {
return nameMap;
} public void setNameMap(Map<String, String> nameMap) {
this.nameMap = nameMap;
} 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 int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} @Override
public String toString() {
return "People [id=" + id + ", name=" + name + ", age=" + age + ", nameMap=" + nameMap + "]";
} }
<?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="people" class="com.fuwh.test.People">
<property name="id" value="1"></property>
<property name="name" value="laofu"></property>
<property name="age" value="27"></property> <property name="nameMap">
<map>
<entry>
<key><value>zhangsan</value></key>
<value>张三</value>
</entry>
<entry>
<key><value>lisi</value></key>
<value>李四</value>
</entry>
</map>
</property>
</bean> </beans>
package com.fuwh.test; import org.junit.Before;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { private ApplicationContext ac; @Before
public void setUp() throws Exception {
ac=new ClassPathXmlApplicationContext("beans.xml");
} @org.junit.Test
public void test() {
People people =(People)ac.getBean("people"); System.out.println(people);
} }
注入属性
package com.fuwh.test; import java.util.Properties; public class People { private int id;
private String name;
private int age; private Properties address=new Properties(); public Properties getAddress() {
return address;
} public void setAddress(Properties address) {
this.address = address;
} 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 int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} @Override
public String toString() {
return "People [id=" + id + ", name=" + name + ", age=" + age + ", address=" + address + "]";
} }
<?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="people" class="com.fuwh.test.People">
<property name="id" value="1"></property>
<property name="name" value="laofu"></property>
<property name="age" value="27"></property> <property name="address">
<props>
<prop key="sheng">shanghai</prop>
<prop key="shi">pudong</prop>
</props>
</property>
</bean> </beans>
package com.fuwh.test; import org.junit.Before;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { private ApplicationContext ac; @Before
public void setUp() throws Exception {
ac=new ClassPathXmlApplicationContext("beans.xml");
} @org.junit.Test
public void test() {
People people =(People)ac.getBean("people"); System.out.println(people);
} }
bean的自动装配
bean的自动装配总共分为四种方式:
no |
(Default) No autowiring. Bean references must be defined via a |
byName |
Autowiring by property name. Spring looks for a bean with the same name as the property that needs to be autowired. For example, if a bean definition is set to autowire by name, and it contains a master property (that is, it has a setMaster(..) method), Spring looks for a bean definition named |
byType |
Allows a property to be autowired if exactly one bean of the property type exists in the container. If more than one exists, a fatal exception is thrown, which indicates that you may not use byType autowiring for that bean. If there are no matching beans, nothing happens; the property is not set. |
constructor |
Analogous to byType, but applies to constructor arguments. If there is not exactly one bean of the constructor argument type in the container, a fatal error is r |
package com.fuwh.test; public class People { private int id;
private String name;
private int age; private Dog dog; public Dog getDog() {
return dog;
} public void setDog(Dog dog) {
this.dog = dog;
} 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 int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} @Override
public String toString() {
return "People [id=" + id + ", name=" + name + ", age=" + age + ", dog=" + dog + "]";
} }
<?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="dog" class="com.fuwh.test.Dog">
<property name="id" value="001"></property>
<property name="name" value="heihu"></property>
<property name="age" value="5"></property>
</bean> <!-- 也可以在beans中定义autowire="byName" 这时候就对所有bean有效-->
<bean id="people" class="com.fuwh.test.People" autowire="byName">
<property name="id" value="1"></property>
<property name="name" value="lisi"></property>
<property name="age" value="27"></property>
</bean> </beans>
package com.fuwh.test; import org.junit.Before;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { private ApplicationContext ac; @Before
public void setUp() throws Exception {
ac=new ClassPathXmlApplicationContext("beans.xml");
} @org.junit.Test
public void test() {
People people =(People)ac.getBean("people");
System.out.println(people);
}
}