初识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="巴黎的雨季"></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="巴黎的雨季" index="0"/>
           <constructor-arg value="男" index="1"/>
           <constructor-arg value="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="奔驰"></property>
           <property name="business" value="上海"></property>
           <property name="price" value="300000"></property>
   </bean>

    <!-- 配置person  引用Car -->
   <bean id="person" class="cn.ljy.clazz.Person">
           <property name="name" value="巴黎的雨季"></property>
           <property name="age" value="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="巴黎的雨季"></property>
           <property name="age" value="18"></property>
           <!-- 注意:内部bean只能在内部使用,不能被外部所引用 -->
           <property name="car" >
               <bean class="cn.ljy.clazz.Car">
                   <property name="brand" value="福特"></property>
                   <property name="business" value="北京"></property>
                   <property name="price" value="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="巴黎的雨季"></property>
           <property name="age" value="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="巴黎的雨季"></property>
           <property name="age" value="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="法拉利"></property>
                           <property name="business" value="上海"></property>
                           <property name="price" value="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="巴黎的雨季"></property>
   </bean>

   <!-- 通过构造器的方式传入参数 -->
   <bean id="AttributeByConstructor1" class="cn.ljy.clazz.HelloWord">
           <!-- 通过构造器方式传参 -->
           <constructor-arg value="巴黎的雨季" index="0"/>
           <constructor-arg value="男" index="1"/>
           <constructor-arg value="18" type="int"/>
   </bean>

   <!--给第二个构造器赋值  -->
   <bean id="AttributeByConstructor2" class="cn.ljy.clazz.HelloWord">
           <!-- 通过构造器方式传参 -->
           <constructor-arg value="巴黎的雨季" index="0"/>
           <constructor-arg name="sex" value="男"  />
           <constructor-arg value="130"  type="double"/>
   </bean>

   <!-- 监管Car 准备三car-->
   <bean id="car" class="cn.ljy.clazz.Car">
           <property name="brand" value="奔驰"></property>
           <property name="business" value="上海"></property>
           <property name="price" value="300000"></property>
   </bean>
   <bean id="car2" class="cn.ljy.clazz.Car">
           <property name="brand" value="大众"></property>
           <property name="business" value="广州"></property>
           <property name="price" value="120000"></property>
   </bean>
   <bean id="car3" class="cn.ljy.clazz.Car">
           <property name="brand" value="雪佛兰"></property>
           <property name="business" value="深圳"></property>
           <property name="price" value="150000"></property>
   </bean>

   <!-- 配置person  引用Car -->
   <bean id="person" class="cn.ljy.clazz.Person">
           <property name="name" value="巴黎的雨季"></property>
           <property name="age" value="18"></property>
           <property name="car" ref="car"></property>
   </bean>

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

   <!-- 级联属性的使用 -->
   <bean id="person3" class="cn.ljy.clazz.Person">
           <property name="name" value="巴黎的雨季"></property>
           <property name="age" value="18"></property>
           <property name="car" ref="car"></property>
           <!-- 级联,改变原来的值    注意:必须是存在car对象才可以,Spring不会自动的创建car -->
           <property name="car.brand" value="劳斯莱斯"></property>
   </bean>

   <!-- list集合属性的配置 -->
   <bean id="people" class="cn.ljy.clazz.People">
           <property name="name" value="巴黎的雨季"></property>
           <property name="age" value="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="巴黎的雨季"></property>
           <property name="age" value="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="法拉利"></property>
                           <property name="business" value="上海"></property>
                           <property name="price" value="4000000"></property>
                       </bean>
                   </entry>
               </map>
           </property>
   </bean>

   <!-- 配置properties属性-->
   <bean id="people3" class="cn.ljy.clazz.NewPeople">
           <property name="name" value="巴黎的雨季"></property>
           <property name="age" value="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="巴黎的雨季"></property>
           <property name="age" value="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="巴黎的雨季"></property>
           <property name="age" value="18"></property>
   </bean>

</beans>  
时间: 2024-08-05 16:18:07

初识Spring框架实现IOC和DI(依赖注入)的相关文章

spring框架学习(二)依赖注入

转自:http://blog.csdn.net/lishuangzhe7047/article/details/20740835 ———————————————————————————————————————————— spring框架为我们提供了三种注入方式,分别是set注入,构造方法注入,接口注入.接口注入不作要求,下面介绍前两种方式. 1,set注入 采用属性的set方法进行初始化,就成为set注入. 1)给普通字符类型赋值. [java] view plaincopyprint? pub

Spring框架之控制反转和依赖注入

学Spring框架必须理解控制反转和依赖注入.下面各自举一个例子,来说明. IOC(控制反转):应用本身创建和维护的依赖对象:现在交由外部容器(Spring)来创建和维护:这个控制权的转移: 就叫做控制反转. 第一步:配置applicationContextcreateproject.xml和applicationcontext.xml(总体) <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=

框架 day36 Spring3 入门,DI依赖注入,装配bean基于xml/注解, 整合Junit4,配置约束自动提示

1 什么是spring 1.1官网 spring.io 1.2介绍 Spring的核心是控制反转(IoC)和面向切面(AOP). IoC(Inverse of Control 反转控制) AOP(Aspect Oriented Programming 面向切面编程为内核) 简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架. *轻量级:依赖其他内容较小,使用资源消耗也少.对比:EJB 重量级 *分层:经典三层体系架构,spring 提供解决方案

Spring:(二)DI依赖注入方式

DI 依赖注入 DI(Dependency Injection)依赖注入,说简单一点就将类里面的属性在创建类的过程中给属性赋值,即将对象依赖属性(简单值,集合,对象)通过配置设值给该对象. 属性注入的方式 构造方法的方式 set方法的方式 工厂方法注入 主要学习前两种方式 构造方法的方式 当是构造方法时注入Bean的属性值(简单值,集合,对象) 利用<constructor-arg>标签进行属性的注入 name:被设置属性的名 value:被设置属性的值 编写用构造方法的pojo 1 pack

浅谈spring框架的控制反转和依赖注入

spring是什么? spring是一个轻量级的控制反转和面向切面编程的开源容器框架. 轻量级是说spring框架本身的体积小. 控制反转(Ioc):它不是技术,而是一种思想,将创建对象的控制权力交给spring框架. 依赖注入(DI):将对象中的属性通过配置文件的方式进行赋值. 面向切面编程(AOP):零散存在于业务层中的功能代码(例如:日志,事务),称为横切面关注点.把一个个横切面关注点放到某个模块中,称为切面. AOP就是把多个方法前后的共同代码抽离出来,使用动态代理机制来控制.好处是降低

控制反转(IoC)与依赖注入(DI)

前言 最近在学习Spring框架,它的核心就是IoC容器.要掌握Spring框架,就必须要理解控制反转的思想以及依赖注入的实现方式.下面,我们将围绕下面几个问题来探讨控制反转与依赖注入的关系以及在Spring中如何应用. 什么是控制反转? 什么是依赖注入? 它们之间有什么关系? 如何在Spring框架中应用依赖注入? 什么是控制反转 在讨论控制反转之前,我们先来看看软件系统中耦合的对象.图1:软件系统中耦合的对象从图中可以看到,软件中的对象就像齿轮一样,协同工作,但是互相耦合,一个零件不能正常工

Spring框架 之IOC容器 和AOP详解

主要分析点: 一.Spring开源框架的简介  二.Spring下IOC容器和DI(依赖注入Dependency injection) 三.Spring下面向切面编程(AOP)和事务管理配置  一.Spring开源框架的简介  Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来.它是为了解决企业应用开

好程序员Java干货分享Spring框架之IOC原理

好程序员Java干货分享Spring框架之IOC原理,前言:Spring框架是我们进行企业级开发的最常用框架,本章我们将了解Spring框架,并学习Spring的IOC特性以及IOC的实现原理:注解和反射. Spring框架简介 Spring是一种轻量级的控制反转(IOC)和面向切面编程(AOP)的容器框架,能够为企业级开发提供一站式服务. Spring的优点有 1.方便解耦,简化开发 通过Spring提供的IoC容器,我们可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度

用IDEA详解Spring中的IoC和DI(挺透彻的,点进来看看吧)

用IDEA详解Spring中的IoC和DI 一.Spring IoC的基本概念 控制反转(IoC)是一个比较抽象的概念,它主要用来消减计算机程序的耦合问题,是Spring框架的核心.依赖注入(DI)是IoC的另外一种说法,只是从不同的角度描述相同的概念.看完这两句,是不是不但没懂,反而更迷惑了,别急,往下看: IoC的背景 我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑. 如果我们打开机械式手表的后盖,就会看到与