首页 > 代码库 > 初识Spring框架实现IOC和DI(依赖注入)

初识Spring框架实现IOC和DI(依赖注入)

学习过Spring框架的人一定都会听过Spring的IoC(控制反转) 、DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC 、DI这两个概念是模糊不清的,是很难理解的,

IoC是什么

  Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。

  在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。如何理解好Ioc呢?理解好Ioc的关键是要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”,那我们来深入分析一下:

  ●谁控制谁,控制什么:传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对 象的创建;谁控制谁?当然是IoC 容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。

  ●为何是反转,哪些方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。

  用图例说明一下,传统程序设计如图2-1,都是主动去创建相关对象然后再组合起来:

                                技术分享

 

当有了IoC/DI的容器后,在客户端类中不再主动去创建这些对象了,如图2-2所示:

                                       技术分享

 

以上就是简单的IOC的理解

那么接下来我们就来实现下我们自己的第一个Spring示例

1.1我们准备一个HelloWord类

 

package cn.ljy.clazz;public class HelloWord {    //名称    private String name;    //性别    private String sex;    //年龄    private int age;    //体重    private double weight;            //准备构造函数        //无参构造   初始化IOC容器时需要    public HelloWord() {            }    //姓名   性别   年龄的构造    public HelloWord(String name, String sex, int age) {        this.name = name;        this.sex = sex;        this.age = age;    }    //姓名  性别   体重的构造    public HelloWord(String name, String sex, double weight) {        this.name = name;        this.sex = sex;        this.weight = weight;    }    public String sayHello(){        return "HelloWord"+name;    }            public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    @Override    public String toString() {        return "HelloWord [name=" + name + ", sex=" + sex + ", age=" + age                + ", weight=" + weight + "]";    }    }    

 

 

 

1.2我们必须得准备一个applicationContext.xml文件

 

<?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:util="http://www.springframework.org/schema/util"    xsi:schemaLocation="        http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/util          http://www.springframework.org/schema/util/spring-util-3.1.xsd        ">   <!-- 将 HelloWord 类交给Spring容器进行管理-->   <!-- 通过属性的方式传入参数 -->   <bean id="HelloWord" class="cn.ljy.clazz.HelloWord">           <!-- 为参数赋值 -->           <property name="name" value=http://www.mamicode.com/"巴黎的雨季"></property>   </bean></beans>  

技术分享

 

 这样就整理好了第一个配置文件了,然后我们进行一道测试

package cn.ljy.test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import cn.ljy.clazz.HelloWord;import cn.ljy.clazz.NewPeople;import cn.ljy.clazz.People;import cn.ljy.clazz.Person;public class MyTest {    public static void main(String[] args) {        //实例化Spring容器的上下文  (创建IOC容器)        ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");        //通过ApplicationContext的getBean()方法,根据id来获取Bean的实例        HelloWord hello = (HelloWord)context.getBean("HelloWord");        //调用HelloWord类中的方法        System.out.println("通过属性的方式给name赋值:");        String result = hello.sayHello();        System.out.println(result);        }

 

实现结果为:

技术分享

 

 1.3以上在配置文件中使用的是setter方法依赖注入,接下来我们使用构造器的方式来实现依赖注入

applicationContext.xml

<?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:util="http://www.springframework.org/schema/util"    xsi:schemaLocation="        http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/util          http://www.springframework.org/schema/util/spring-util-3.1.xsd        ">   <!-- 将 HelloWord 类交给Spring容器进行管理-->   <!-- 通过构造器的方式传入参数 -->   <bean id="AttributeByConstructor1" class="cn.ljy.clazz.HelloWord">           <!-- 通过构造器方式传参 -->           <constructor-arg value=http://www.mamicode.com/"巴黎的雨季" index="0"/>           <constructor-arg value=http://www.mamicode.com/"" index="1"/>           <constructor-arg value=http://www.mamicode.com/"18" type="int"/>   </bean></beans>  

 

 技术分享

执行结果如图

技术分享

 

1.4使用引用类型,引用自定义的Bean(外部Bean)

准备一个person对象

package cn.ljy.clazz;public class Person {    private String name;    private int age;    private Car car;            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 Car getCar() {        return car;    }    public void setCar(Car car) {        this.car = car;    }    @Override    public String toString() {        return "Person [name=" + name + ", age=" + age + ", car=" + car + "]";    }        }

 

applicationContext.xml

<?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:util="http://www.springframework.org/schema/util"    xsi:schemaLocation="        http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/util          http://www.springframework.org/schema/util/spring-util-3.1.xsd        ">         <!-- 监管Car 准备三car-->   <bean id="car" class="cn.ljy.clazz.Car">           <property name="brand" value=http://www.mamicode.com/"奔驰"></property>           <property name="business" value=http://www.mamicode.com/"上海"></property>           <property name="price" value=http://www.mamicode.com/"300000"></property>   </bean>    <!-- 配置person  引用Car -->   <bean id="person" class="cn.ljy.clazz.Person">           <property name="name" value=http://www.mamicode.com/"巴黎的雨季"></property>           <property name="age" value=http://www.mamicode.com/"18"></property>               <property name="car" ref="car"></property>   </bean>   </bean></beans>  

 

 技术分享

执行结果

技术分享

1.5使用内部Bean

 

<!-- 内部bean   -->    <bean id="person2" class="cn.ljy.clazz.Person">           <property name="name" value=http://www.mamicode.com/"巴黎的雨季"></property>           <property name="age" value=http://www.mamicode.com/"18"></property>               <!-- 注意:内部bean只能在内部使用,不能被外部所引用 -->           <property name="car" >               <bean class="cn.ljy.clazz.Car">                   <property name="brand" value=http://www.mamicode.com/"福特"></property>                   <property name="business" value=http://www.mamicode.com/"北京"></property>                   <property name="price" value=http://www.mamicode.com/"400000"></property>               </bean>           </property>   </bean>

技术分享

 

执行结果与上一步基本一致

1.6配置list集合属性

People

package cn.ljy.clazz;import java.util.List;public class People {        private String name;    private int age;    private List<Car> cars;                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 List<Car> getCars() {        return cars;    }    public void setCars(List<Car> cars) {        this.cars = cars;    }    @Override    public String toString() {        return "People [name=" + name + ", age=" + age + ", cars=" + cars + "]";    }        }
<!-- list集合属性的配置 -->   <bean id="people" class="cn.ljy.clazz.People">           <property name="name" value=http://www.mamicode.com/"巴黎的雨季"></property>           <property name="age" value=http://www.mamicode.com/"28"></property>               <property name="cars">               <!-- 使用list节点为集合属性赋值 -->               <list>                   <ref bean="car"/>                   <ref bean="car2"/>                   <ref bean="car3"/>               </list>           </property>   </bean>

 技术分享

 

执行结果

技术分享

1.7使用Map集合配置属性

NewPeople

package cn.ljy.clazz;import java.util.Map;import java.util.Properties;public class NewPeople {    private String name;    private int age;    private Map<String,Car> cars;        //配置properties属性    private Properties properties;        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 Map<String, Car> getCars() {        return cars;    }    public void setCars(Map<String, Car> cars) {        this.cars = cars;    }        public Properties getProperties() {        return properties;    }    public void setProperties(Properties properties) {        this.properties = properties;    }    @Override    public String toString() {        return "NewPeople [name=" + name + ", age=" + age + ", cars=" + cars                + "]";    }        }
 <!--Map集合属性值的配置  -->   <bean id="people2" class="cn.ljy.clazz.NewPeople">           <property name="name" value=http://www.mamicode.com/"巴黎的雨季"></property>           <property name="age" value=http://www.mamicode.com/"28"></property>               <property name="cars">               <map>                   <entry key="OneCar" value-ref="car"></entry>                   <entry key="TwoCar" value-ref="car2"></entry>                   <entry key="Three">                       <bean class="cn.ljy.clazz.Car">                           <property name="brand" value=http://www.mamicode.com/"法拉利"></property>                           <property name="business" value=http://www.mamicode.com/"上海"></property>                           <property name="price" value=http://www.mamicode.com/"4000000"></property>                       </bean>                   </entry>               </map>           </property>   </bean>

技术分享

 以上就是一些基本的常用的依赖注入了,还有几个例子我会在下面的代码中贴出来,因为用的不多,所以就不做详细的讲解了

<?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:aop="http://www.springframework.org/schema/aop"    xmlns:p="http://www.springframework.org/schema/p"    xmlns:util="http://www.springframework.org/schema/util"    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/aop        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd        http://www.springframework.org/schema/util          http://www.springframework.org/schema/util/spring-util-3.1.xsd        http://www.springframework.org/schema/context         http://www.springframework.org/schema/context/spring-context-3.0.xsd        ">                        <!-- 将 HelloWord 类交给Spring容器进行管理-->      <!-- 通过属性的方式传入参数 -->   <bean id="HelloWord" class="cn.ljy.clazz.HelloWord">           <!-- 为参数赋值 -->           <property name="name" value=http://www.mamicode.com/"巴黎的雨季"></property>   </bean>      <!-- 通过构造器的方式传入参数 -->   <bean id="AttributeByConstructor1" class="cn.ljy.clazz.HelloWord">           <!-- 通过构造器方式传参 -->           <constructor-arg value=http://www.mamicode.com/"巴黎的雨季" index="0"/>           <constructor-arg value=http://www.mamicode.com/"" index="1"/>           <constructor-arg value=http://www.mamicode.com/"18" type="int"/>   </bean>      <!--给第二个构造器赋值  -->   <bean id="AttributeByConstructor2" class="cn.ljy.clazz.HelloWord">           <!-- 通过构造器方式传参 -->           <constructor-arg value=http://www.mamicode.com/"巴黎的雨季" index="0"/>           <constructor-arg name="sex" value=http://www.mamicode.com/""  />           <constructor-arg value=http://www.mamicode.com/"130"  type="double"/>   </bean>   <!-- 监管Car 准备三car-->   <bean id="car" class="cn.ljy.clazz.Car">           <property name="brand" value=http://www.mamicode.com/"奔驰"></property>           <property name="business" value=http://www.mamicode.com/"上海"></property>           <property name="price" value=http://www.mamicode.com/"300000"></property>   </bean>   <bean id="car2" class="cn.ljy.clazz.Car">           <property name="brand" value=http://www.mamicode.com/"大众"></property>           <property name="business" value=http://www.mamicode.com/"广州"></property>           <property name="price" value=http://www.mamicode.com/"120000"></property>   </bean>   <bean id="car3" class="cn.ljy.clazz.Car">           <property name="brand" value=http://www.mamicode.com/"雪佛兰"></property>           <property name="business" value=http://www.mamicode.com/"深圳"></property>           <property name="price" value=http://www.mamicode.com/"150000"></property>   </bean>      <!-- 配置person  引用Car -->   <bean id="person" class="cn.ljy.clazz.Person">           <property name="name" value=http://www.mamicode.com/"巴黎的雨季"></property>           <property name="age" value=http://www.mamicode.com/"18"></property>               <property name="car" ref="car"></property>   </bean>      <!-- 内部bean   -->    <bean id="person2" class="cn.ljy.clazz.Person">           <property name="name" value=http://www.mamicode.com/"巴黎的雨季"></property>           <property name="age" value=http://www.mamicode.com/"18"></property>               <!-- 注意:内部bean只能在内部使用,不能被外部所引用 -->           <property name="car" >               <bean class="cn.ljy.clazz.Car">                   <property name="brand" value=http://www.mamicode.com/"福特"></property>                   <property name="business" value=http://www.mamicode.com/"北京"></property>                   <property name="price" value=http://www.mamicode.com/"400000"></property>               </bean>           </property>   </bean>      <!-- 级联属性的使用 -->   <bean id="person3" class="cn.ljy.clazz.Person">           <property name="name" value=http://www.mamicode.com/"巴黎的雨季"></property>           <property name="age" value=http://www.mamicode.com/"18"></property>               <property name="car" ref="car"></property>           <!-- 级联,改变原来的值    注意:必须是存在car对象才可以,Spring不会自动的创建car -->           <property name="car.brand" value=http://www.mamicode.com/"劳斯莱斯"></property>   </bean>         <!-- list集合属性的配置 -->   <bean id="people" class="cn.ljy.clazz.People">           <property name="name" value=http://www.mamicode.com/"巴黎的雨季"></property>           <property name="age" value=http://www.mamicode.com/"28"></property>               <property name="cars">               <!-- 使用list节点为集合属性赋值 -->               <list>                   <ref bean="car"/>                   <ref bean="car2"/>                   <ref bean="car3"/>               </list>           </property>   </bean>      <!--Map集合属性值的配置  -->   <bean id="people2" class="cn.ljy.clazz.NewPeople">           <property name="name" value=http://www.mamicode.com/"巴黎的雨季"></property>           <property name="age" value=http://www.mamicode.com/"28"></property>               <property name="cars">               <map>                   <entry key="OneCar" value-ref="car"></entry>                   <entry key="TwoCar" value-ref="car2"></entry>                   <entry key="Three">                       <bean class="cn.ljy.clazz.Car">                           <property name="brand" value=http://www.mamicode.com/"法拉利"></property>                           <property name="business" value=http://www.mamicode.com/"上海"></property>                           <property name="price" value=http://www.mamicode.com/"4000000"></property>                       </bean>                   </entry>               </map>           </property>   </bean>      <!-- 配置properties属性-->   <bean id="people3" class="cn.ljy.clazz.NewPeople">           <property name="name" value=http://www.mamicode.com/"巴黎的雨季"></property>           <property name="age" value=http://www.mamicode.com/"28"></property>               <property name="properties">               <props>                   <prop key="user">root</prop>                   <prop key="password">123</prop>                   <prop key="jdbcurl">jdbc:mysql:/test</prop>                   <prop key="drivarClass">com.mysql.jdbc.java</prop>               </props>           </property>   </bean>         <!-- 独立出一个bean  比如说list 需要引入新的命名空间  util-->  <!-- <util:list id="cars">           <ref bean="car"/>           <ref bean="car2"/>           <ref bean="car3"/>   </util>      <bean id="people4" class="cn.ljy.clazz.People">           <property name="name" value=http://www.mamicode.com/"巴黎的雨季"></property>           <property name="age" value=http://www.mamicode.com/"28"></property>               <property name="cars" ref="cars"></property>   </bean>  -->         <!-- 自动装配           可以使用autowire属性指定自动装配的方式           byName 根据Bean的名字和当前Bean的setter风格的属性名进行自动装配,若有匹配的,则进行自动装配 ,若没有匹配的则不进行装配            byType 根据Bean的类型和当前Bean的属性的类型进行自动装配,若IOC容器中定义了多个类型匹配的Bean 则会抛出异常    -->    <bean id="person4" class="cn.ljy.clazz.Person" autowire="byName">           <property name="name" value=http://www.mamicode.com/"巴黎的雨季"></property>           <property name="age" value=http://www.mamicode.com/"18"></property>       </bean>         </beans>  

 

初识Spring框架实现IOC和DI(依赖注入)