JAVA-Spring框架之IOC(DI)

Posted xiaoluohao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA-Spring框架之IOC(DI)相关的知识,希望对你有一定的参考价值。

spring框架概述
  spring是一个service层的框架,可以整合许多其 他框架,进行工作
  spring的主要技术是IOC(DI)和AOP

  IOC(DI)-控制反转(依赖注入)AOP - 面向切面编程

1. IOC(DI)

  所谓的IOC称之为控制反转,简单来说,就是将创 建对象的权力和对象的生命周期都由spring框架 来管理,从此开放过程中便不再关心对象的创建 和生命周期的管理,从而在需要创建对象的时候 ,由spring框架提供,这个由spring框架管理对 象的创建和生命周期的机制就是IOC,创建对象的 过程中spring框架可以根据配置对对象的属性进 行设置,这个过程就是依赖注入(DI)。

2.set方法注入

  通常的javabean属性都会被私有化,而对外暴露set和get方法,此时spring可以通过这样的set方法将属性的值注入对象。

  spring内置的可以直接注入的类型:

 1 package cn.tedu.beans;
 2 
 3 import java.util.List;
 4 import java.util.Map;
 5 import java.util.Properties;
 6 import java.util.Set;
 7 
 8 public class Hero 
 9         private int id;
10         private String name;
11         private List<String> jobs;
12         private Set<String> set;
13         private Map<String,String> map;
14         private Properties prop;
15         
16         public void setId(int id) 
17                 this.id = id;
18         
19 
20         public void setName(String name) 
21                 this.name = name;
22         
23 
24         public void setJobs(List<String> jobs) 
25                 this.jobs = jobs;
26         
27 
28         public void setSet(Set<String> set) 
29                 this.set = set;
30         
31 
32         public void setMap(Map<String, String> map) 
33                 this.map = map;
34         
35 
36         public void setProp(Properties prop) 
37                 this.prop = prop;
38         
39 
40         @Override
41         public String toString() 
42                 return "Hero [id=" + id + ", name=" + name + ", jobs=" + jobs
43                                 + ", set=" + set + ", map=" + map + ", prop=" + prop + "]";
44         
45 
 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-3.2.xsd"
 6         >
 7         
 8         <bean id="hero" class="cn.tedu.beans.Hero">
 9                 <property name="id" value="123"></property>
10                 <property name="name" value="亚瑟 "></property>
11                 <property name="jobs">
12                         <list>
13                                 <value>上单</value>
14                                 <value>打野</value>
15                                 <value>辅助</value>
16                                 <value>中单</value>
17                         </list>
18                 </property>
19                 <property name="set">
20                         <set>
21                                 <value>aaa</value>
22                                 <value>bbb</value>
23                                 <value>ccc</value>
24                                 <value>aaa</value>
25                         </set>
26                 </property>
27                 <property name="map">
28                         <map>
29                                  <entry key="addr" value="王者荣耀"></entry>
30                                  <entry key="addr" value="英雄联盟"></entry>
31                                  <entry key="skill" value="风火轮"></entry>
32                                  <entry key="age" value="19"></entry>
33                         </map>
34                 </property>
35                 <property name="prop">
36                         <props>
37                                 <prop key="k1">v1</prop>
38                                 <prop key="k2">v2</prop>
39                                 <prop key="k3">v3</prop>
40                                 <prop key="k4">v4</prop>
41                         </props>
42                 </property>
43         </bean>
44 
45 </beans>

 

1 @Test
2 /**
3  * SpringDI set方式属性注入 - Spring内置的可直接注入类型的注入
4  */
5 public void test1()
6         ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
7         Hero hero = (Hero) context.getBean("hero");
8         System.out.println(hero);
9 

  非spring内置的可以直接如注入的类型:

 1 package cn.tedu.beans;
 2 
 3 import java.util.List;
 4 import java.util.Map;
 5 import java.util.Properties;
 6 import java.util.Set;
 7 
 8 public class Hero 
 9         private int id;
10         private String name;
11         private List<String> jobs;
12         private Set<String> set;
13         private Map<String,String> map;
14         private Properties prop;
15         private Dog dog;
16         private Cat cat;
17         
18         
19         public void setId(int id) 
20                 this.id = id;
21         
22 
23         public void setName(String name) 
24                 this.name = name;
25         
26 
27         public void setJobs(List<String> jobs) 
28                 this.jobs = jobs;
29         
30 
31         public void setSet(Set<String> set) 
32                 this.set = set;
33         
34 
35         public void setMap(Map<String, String> map) 
36                 this.map = map;
37         
38 
39         public void setProp(Properties prop) 
40                 this.prop = prop;
41         
42 
43         public void setDog(Dog dog) 
44                 this.dog = dog;
45         
46 
47         public void setCat(Cat cat) 
48                 this.cat = cat;
49         
50 
51         @Override
52         public String toString() 
53                 return "Hero [id=" + id + ", name=" + name + ", jobs=" + jobs
54                                 + ", set=" + set + ", map=" + map + ", prop=" + prop + ", dog="
55                                 + dog + ", cat=" + cat + "]";
56         
57 
58 
 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-3.2.xsd"
 6         >
 7         
 8         <bean id="hero" class="cn.tedu.beans.Hero">
 9                 <property name="id" value="123"></property>
10                 <property name="name" value="亚瑟 "></property>
11                 <property name="jobs">
12                         <list>
13                                 <value>上单</value>
14                                 <value>打野</value>
15                                 <value>辅助</value>
16                                 <value>中单</value>
17                         </list>
18                 </property>
19                 <property name="set">
20                         <set>
21                                 <value>aaa</value>
22                                 <value>bbb</value>
23                                 <value>ccc</value>
24                                 <value>aaa</value>
25                         </set>
26                 </property>
27                 <property name="map">
28                         <map>
29                                  <entry key="addr" value="王者荣耀"></entry>
30                                  <entry key="addr" value="英雄联盟"></entry>
31                                  <entry key="skill" value="风火轮"></entry>
32                                  <entry key="age" value="19"></entry>
33                         </map>
34                 </property>
35                 <property name="prop">
36                         <props>
37                                 <prop key="k1">v1</prop>
38                                 <prop key="k2">v2</prop>
39                                 <prop key="k3">v3</prop>
40                                 <prop key="k4">v4</prop>
41                         </props>
42                 </property>
43                 <property name="dog" ref="dog"></property>
44                 <property name="cat" ref="cat"></property>
45         </bean>
46 
47         <bean id="dog" class="cn.tedu.beans.Dog"></bean>
48         <bean id="cat" class="cn.tedu.beans.Cat"></bean>
49         
50 </beans>

技术图片

1 @Test
2 /**
3  * SpringDI set方式属性注入 - 非Spring内置的可以直接注入类型的注入
4  */
5 public void test2()
6         ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
7         Hero hero = (Hero) context.getBean("hero");
8         System.out.println(hero);
9 

  3.自动装配

    在spring的set方式实现的注入过程中,支持自动装配机制,所谓自动装配机制,会根据要设置的javabean属性的名字或者类型到spring中自动寻找对应id或类型的<bean>进行设置,从而省去一次配置的过程,简化了配置。

  为指定的<bean>开启自动装配:

 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-3.2.xsd"
 6         >
 7         
 8         <!-- 
 9                 autowire设定自动装配:
10                         byName:根据javabean中需要注入的属性的名字 ,在spring容器中找对应id的<bean>将该<bean>的对象复制给 当前的属性 
11                         byType:根据javabean中需要注入的属性的类型,在spring容器中找对应class类型的<bean>将该<bean>的对象复制给 当前的属性
12                         **byType方式 根据类型进行匹配,可能匹配到多个<bean>,此时会抛出异常。而byName是通过id来寻找<bean>,id没有重复,不会有这方面的问题,所以推荐使用byName方式
13          -->
14         <bean id="teacher" class="cn.tedu.beans.Teacher" autowire="byName"></bean>
15         <bean id="dog" class="cn.tedu.beans.Dog"></bean>
16         <bean id="cat" class="cn.tedu.beans.Cat"></bean>
17         
18 </beans>

  为全局配置自动装配:

 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-3.2.xsd"
 6         default-autowire="byName"
 7         >
 8         
 9         <!-- 
10                 autowire设定自动装配:
11                         byName:根据javabean中需要注入的属性的名字 ,在spring容器中找对应id的<bean>将该<bean>的对象复制给 当前的属性 
12                         byType:根据javabean中需要注入的属性的类型,在spring容器中找对应class类型的<bean>将该<bean>的对象复制给 当前的属性
13                         **byType方式 根据类型进行匹配,可能匹配到多个<bean>,此时会抛出异常。而byName是通过id来寻找<bean>,id没有重复,不会有这方面的问题,所以推荐使用byName方式
14          -->
15         <bean id="teacher" class="cn.tedu.beans.Teacher"></bean>
16         <bean id="dog" class="cn.tedu.beans.Dog"></bean>
17         <bean id="cat" class="cn.tedu.beans.Cat"></bean>
18         
19 </beans>
 1 package cn.tedu.beans;
 2 
 3 public class Teacher 
 4         private Dog dog;
 5         private Cat cat;
 6         public void setDog(Dog dog) 
 7                 this.dog = dog;
 8         
 9         public void setCat(Cat cat) 
10                 this.cat = cat;
11         
12         
13         @Override
14         public String toString() 
15                 return "Teacher [dog=" + dog + ", cat=" + cat + "]";
16         
17 
1 @Test
2 /**
3  * SpringDI 自动装配
4  */
5 public void test4()
6     ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
7     Teacher teacher = (Teacher) context.getBean("teacher");
8     System.out.println(teacher);
9 

  4.基于构造方法的注入:

    对象属性设置的另一种方式是在对象创建的过程中通过构造方法的传入并设置对象的属性的。spring也可以通过这样的构造方法实现属性的注入。

 

 1 package cn.tedu.beans;
 2 
 3 public class Student 
 4         private int id;
 5         private String name;
 6         private Dog dog;
 7         
 8         public Student(int id, String name, Dog dog) 
 9                 this.id = id;
10                 this.name = name;
11                 this.dog = dog;
12         
13 
14         @Override
15         public String toString() 
16                 return "Student [id=" + id + ", name=" + name + ", dog=" + dog + "]";
17         
18 
 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-3.2.xsd"
 6         >
 7         
 8         <bean id="student" class="cn.tedu.beans.Student">
 9                 <!-- 
10                         index:为构造方法的第几个参数 进行配置
11                         name:为构造方法的哪个名字的参数进行配置
12                                  **index 和 name 可以配置任何一个或同时配置 但要求一旦配置必须正确
13                                  **推荐优先使用index方式配置 防止没有源码造成name无法匹配到对应参数
14                         type:该构造方法参数的类型
15                         value:该构造方法参数的值 ,用来指定基本值
16                         ref:该构造方法参数的值,用来指定引用其他bean的值
17                  -->
18                 <constructor-arg index="0" name="id" value="999"/>
19                 <constructor-arg index="1" type="java.lang.String" value="张无忌"/>
20                 <constructor-arg name="dog" ref="dog"/>
21         </bean>
22         
23         <bean id="dog" class="cn.tedu.beans.Dog"></bean>
24         
25 </beans>
1 @Test
2 /**
3  * SpringDI 构造方法方式属性注入
4  */
5 public void test3()
6         ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
7         Student student = (Student) context.getBean("student");
8         System.out.println(student);
9 

 

以上是关于JAVA-Spring框架之IOC(DI)的主要内容,如果未能解决你的问题,请参考以下文章

认识Spring核心容器IoC/DI

认识Spring核心容器IoC/DI

学习笔记--Spring框架

Spring之IOC和DI

Spring之IoC总结帖

Spring5源码分析(004)——IoC篇之理解Ioc