DI:Dependency Injection(依赖注入),通俗的讲就是一种通过xml配置文件,为交给sping容器的对象初始化参数。又称做控制反转:Inversion of Control(IoC)
依赖注入主要分为四种形式:
|-:基于构造方法的依赖注入
|-:基于setter方法的依赖注入
|-:基于工厂的注入
|-:基于泛型的注入
基于构造方法的依赖注入又可以分为以下几种:
·复杂数据类型:
·简单数据类型:
|- 基于属性类型(type)
|-基于索引(index)
|-基于参数名称(name)
复杂数据类型实例
1 package com.fuwh.spring; 2 3 4 /* 5 * POJO类 6 */ 7 public class Clazz { 8 9 private String name; 10 private int grade; 11 public String getName() { 12 return name; 13 } 14 public void setName(String name) { 15 this.name = name; 16 } 17 public int getGrade() { 18 return grade; 19 } 20 public void setGrade(int grade) { 21 this.grade = grade; 22 } 23 24 } 25 package com.fuwh.spring; 26 /* 27 * POJO类 28 */ 29 public class Lesson { 30 31 private String name; 32 private int score; 33 public String getName() { 34 return name; 35 } 36 public void setName(String name) { 37 this.name = name; 38 } 39 public int getScore() { 40 return score; 41 } 42 public void setScore(int score) { 43 this.score = score; 44 } 45 46 } 47 package com.fuwh.spring; 48 49 public class Student { 50 51 private Clazz clazz; 52 private Lesson lesson; 53 54 public Student(Clazz clazz, Lesson lesson) { 55 this.clazz = clazz; 56 this.lesson = lesson; 57 } 58 59 @Override 60 public String toString() { 61 return "Student [clazz=" + clazz.getGrade()+clazz.getName() + ", lesson=" + lesson.getName()+","+lesson.getScore() + "学分]"; 62 } 63 64 } 65 66 67 68 <?xml version="1.0" encoding="UTF-8"?> 69 70 71 <beans xmlns="http://www.springframework.org/schema/beans" 72 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 73 xsi:schemaLocation="http://www.springframework.org/schema/beans 74 http://www.springframework.org/schema/beans/spring-beans.xsd"> 75 76 <!-- 配置文件 --> 77 78 <bean id="student" class="com.fuwh.spring.Student" lazy-init="default"> 79 <constructor-arg ref="clazz"/> 80 <constructor-arg ref="lesson"/> 81 </bean> 82 83 84 <bean id="clazz" class="com.fuwh.spring.Clazz"> 85 <property name="name" value="信本"/> 86 <property name="grade" value="08"/> 87 </bean> 88 <bean id="lesson" class="com.fuwh.spring.Lesson"> 89 <property name="name" value="java"/> 90 <property name="score" value="4"/> 91 </bean> 92 </beans> 93 94 95 96 package com.fuwh.spring; 97 98 99 100 import org.springframework.context.ApplicationContext; 101 import org.springframework.context.support.ClassPathXmlApplicationContext; 102 103 public class Spring01 { 104 105 public static void main(String[] args) { 106 /* 107 * 测试类 108 */ 109 ApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml"); 110 System.out.println(ac.getBean("student",Student.class)); 111 } 112 }
基于属性类型(type) 实例:
1 package com.fuwh.spring; 2 /* 3 * POJO类 4 */ 5 public class Clazz { 6 7 private String name; 8 private int grade; 9 10 public Clazz(String name, int grade) { 11 super(); 12 this.name = name; 13 this.grade = grade; 14 } 15 @Override 16 public String toString() { 17 return "Student [name=" + name + ", grade=" + grade + "]"; 18 } 19 20 }
<?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.
级联属性注入
1 package com.fuwh.test; 2 3 public class People { 4 5 public int id; 6 public String name; 7 public int age; 8 9 public Dog dog=new Dog(); 10 11 public int getId() { 12 return id; 13 } 14 15 public void setId(int id) { 16 this.id = id; 17 } 18 19 public String getName() { 20 return name; 21 } 22 23 public void setName(String name) { 24 this.name = name; 25 } 26 27 public int getAge() { 28 return age; 29 } 30 31 public void setAge(int age) { 32 this.age = age; 33 } 34 35 public Dog getDog() { 36 return dog; 37 } 38 39 public void setDog(Dog dog) { 40 this.dog = dog; 41 } 42 43 @Override 44 public String toString() { 45 return "People [id=" + id + ", name=" + name + ", age=" + age + ", dog=" + dog + "]"; 46 } 47 48 49 50 }
1 package com.fuwh.test; 2 3 public class Dog { 4 5 public int id; 6 public String name; 7 public int age; 8 public int getId() { 9 return id; 10 } 11 public void setId(int id) { 12 this.id = id; 13 } 14 public String getName() { 15 return name; 16 } 17 public void setName(String name) { 18 this.name = name; 19 } 20 public int getAge() { 21 return age; 22 } 23 public void setAge(int age) { 24 this.age = age; 25 } 26 @Override 27 public String toString() { 28 return "Dog [id=" + id + ", name=" + name + ", age=" + age + "]"; 29 } 30 31 32 }
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans.xsd"> 6 7 <bean id="people" class="com.fuwh.test.People"> 8 <property name="id" value="1"></property> 9 <property name="name" value="laofu"></property> 10 <property name="age" value="27"></property> 11 12 <!-- dog就是属于级联的初始化 --> 13 <property name="dog.id" value="12"></property> 14 <property name="dog.name" value="wangcai"></property> 15 <property name="dog.age" value="11"></property> 16 </bean> 17 18 19 20 </beans>
最后,使用junit4进行测试
1 package com.fuwh.test; 2 3 4 import org.junit.Before; 5 import org.springframework.context.ApplicationContext; 6 import org.springframework.context.support.ClassPathXmlApplicationContext; 7 8 public class Test { 9 10 private ApplicationContext ac; 11 12 13 @Before 14 public void setUp() throws Exception { 15 ac=new ClassPathXmlApplicationContext("beans.xml"); 16 } 17 18 @org.junit.Test 19 public void test() { 20 People people =(People)ac.getBean("people"); 21 System.out.println(people); 22 } 23 24 }
注入集合变量
List
1 package com.fuwh.test; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 public class People { 7 8 public int id; 9 public String name; 10 public int age; 11 12 public List<String> nameList=new ArrayList<String>(); 13 14 15 16 public List<String> getNameList() { 17 return nameList; 18 } 19 20 public void setNameList(List<String> nameList) { 21 this.nameList = nameList; 22 } 23 24 public int getId() { 25 return id; 26 } 27 28 public void setId(int id) { 29 this.id = id; 30 } 31 32 public String getName() { 33 return name; 34 } 35 36 public void setName(String name) { 37 this.name = name; 38 } 39 40 public int getAge() { 41 return age; 42 } 43 44 public void setAge(int age) { 45 this.age = age; 46 } 47 48 @Override 49 public String toString() { 50 return "People [id=" + id + ", name=" + name + ", age=" + age + ", nameList=" + nameList + "]"; 51 } 52 53 54 55 56 }
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans.xsd"> 6 7 <bean id="people" class="com.fuwh.test.People"> 8 <property name="id" value="1"></property> 9 <property name="name" value="laofu"></property> 10 <property name="age" value="27"></property> 11 12 <property name="nameList"> 13 <list> 14 <value>唱歌</value> 15 <value>跳舞</value> 16 <value>编程</value> 17 </list> 18 </property> 19 </bean> 20 21 22 23 </beans>
1 package com.fuwh.test; 2 3 4 import org.junit.Before; 5 import org.springframework.context.ApplicationContext; 6 import org.springframework.context.support.ClassPathXmlApplicationContext; 7 8 public class Test { 9 10 private ApplicationContext ac; 11 12 13 @Before 14 public void setUp() throws Exception { 15 ac=new ClassPathXmlApplicationContext("beans.xml"); 16 } 17 18 @org.junit.Test 19 public void test() { 20 People people =(People)ac.getBean("people"); 21 22 System.out.println(people); 23 } 24 25 }
map
1 package com.fuwh.test; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 6 public class People { 7 8 public int id; 9 public String name; 10 public int age; 11 12 public Map<String,String> nameMap=new HashMap<String,String>(); 13 14 public Map<String, String> getNameMap() { 15 return nameMap; 16 } 17 18 public void setNameMap(Map<String, String> nameMap) { 19 this.nameMap = nameMap; 20 } 21 22 public int getId() { 23 return id; 24 } 25 26 public void setId(int id) { 27 this.id = id; 28 } 29 30 public String getName() { 31 return name; 32 } 33 34 public void setName(String name) { 35 this.name = name; 36 } 37 38 public int getAge() { 39 return age; 40 } 41 42 public void setAge(int age) { 43 this.age = age; 44 } 45 46 @Override 47 public String toString() { 48 return "People [id=" + id + ", name=" + name + ", age=" + age + ", nameMap=" + nameMap + "]"; 49 } 50 51 }
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans.xsd"> 6 7 <bean id="people" class="com.fuwh.test.People"> 8 <property name="id" value="1"></property> 9 <property name="name" value="laofu"></property> 10 <property name="age" value="27"></property> 11 12 <property name="nameMap"> 13 <map> 14 <entry> 15 <key><value>zhangsan</value></key> 16 <value>张三</value> 17 </entry> 18 <entry> 19 <key><value>lisi</value></key> 20 <value>李四</value> 21 </entry> 22 </map> 23 </property> 24 </bean> 25 26 27 28 </beans>
1 package com.fuwh.test; 2 3 4 import org.junit.Before; 5 import org.springframework.context.ApplicationContext; 6 import org.springframework.context.support.ClassPathXmlApplicationContext; 7 8 public class Test { 9 10 private ApplicationContext ac; 11 12 13 @Before 14 public void setUp() throws Exception { 15 ac=new ClassPathXmlApplicationContext("beans.xml"); 16 } 17 18 @org.junit.Test 19 public void test() { 20 People people =(People)ac.getBean("people"); 21 22 System.out.println(people); 23 } 24 25 }
注入属性
1 package com.fuwh.test; 2 3 import java.util.Properties; 4 5 public class People { 6 7 private int id; 8 private String name; 9 private int age; 10 11 private Properties address=new Properties(); 12 13 public Properties getAddress() { 14 return address; 15 } 16 17 public void setAddress(Properties address) { 18 this.address = address; 19 } 20 21 public int getId() { 22 return id; 23 } 24 25 public void setId(int id) { 26 this.id = id; 27 } 28 29 public String getName() { 30 return name; 31 } 32 33 public void setName(String name) { 34 this.name = name; 35 } 36 37 public int getAge() { 38 return age; 39 } 40 41 public void setAge(int age) { 42 this.age = age; 43 } 44 45 @Override 46 public String toString() { 47 return "People [id=" + id + ", name=" + name + ", age=" + age + ", address=" + address + "]"; 48 } 49 50 }
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans.xsd"> 6 7 <bean id="people" class="com.fuwh.test.People"> 8 <property name="id" value="1"></property> 9 <property name="name" value="laofu"></property> 10 <property name="age" value="27"></property> 11 12 <property name="address"> 13 <props> 14 <prop key="sheng">shanghai</prop> 15 <prop key="shi">pudong</prop> 16 </props> 17 </property> 18 </bean> 19 20 21 22 </beans>
1 package com.fuwh.test; 2 3 4 import org.junit.Before; 5 import org.springframework.context.ApplicationContext; 6 import org.springframework.context.support.ClassPathXmlApplicationContext; 7 8 public class Test { 9 10 private ApplicationContext ac; 11 12 13 @Before 14 public void setUp() throws Exception { 15 ac=new ClassPathXmlApplicationContext("beans.xml"); 16 } 17 18 @org.junit.Test 19 public void test() { 20 People people =(People)ac.getBean("people"); 21 22 System.out.println(people); 23 } 24 25 }
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 |
1 package com.fuwh.test; 2 3 public class People { 4 5 private int id; 6 private String name; 7 private int age; 8 9 private Dog dog; 10 11 public Dog getDog() { 12 return dog; 13 } 14 15 public void setDog(Dog dog) { 16 this.dog = dog; 17 } 18 19 public int getId() { 20 return id; 21 } 22 23 public void setId(int id) { 24 this.id = id; 25 } 26 27 public String getName() { 28 return name; 29 } 30 31 public void setName(String name) { 32 this.name = name; 33 } 34 35 public int getAge() { 36 return age; 37 } 38 39 public void setAge(int age) { 40 this.age = age; 41 } 42 43 @Override 44 public String toString() { 45 return "People [id=" + id + ", name=" + name + ", age=" + age + ", dog=" + dog + "]"; 46 } 47 48 49 }
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans.xsd"> 6 7 <bean id="dog" class="com.fuwh.test.Dog"> 8 <property name="id" value="001"></property> 9 <property name="name" value="heihu"></property> 10 <property name="age" value="5"></property> 11 </bean> 12 13 <!-- 也可以在beans中定义autowire="byName" 这时候就对所有bean有效--> 14 <bean id="people" class="com.fuwh.test.People" autowire="byName"> 15 <property name="id" value="1"></property> 16 <property name="name" value="lisi"></property> 17 <property name="age" value="27"></property> 18 </bean> 19 20 </beans>
1 package com.fuwh.test; 2 3 4 import org.junit.Before; 5 import org.springframework.context.ApplicationContext; 6 import org.springframework.context.support.ClassPathXmlApplicationContext; 7 8 public class Test { 9 10 private ApplicationContext ac; 11 12 @Before 13 public void setUp() throws Exception { 14 ac=new ClassPathXmlApplicationContext("beans.xml"); 15 } 16 17 @org.junit.Test 18 public void test() { 19 People people =(People)ac.getBean("people"); 20 System.out.println(people); 21 } 22 }