Spring学习笔记 IOC之依赖注入

1.概述

控制反转(Inversion of Control,英文缩写为IOC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题,也是轻量级的Spring框架的核心。 控制反转一般分为两种类型,依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup),依赖注入应用的更加广泛一些。概念没听明白?没有关系,还是通过具体的实例来认识一下依赖注入的魅力吧。

2.普通的创建对象

在没有使用Spring框架之前,我们创建一个普通的javabean对象的步骤是这样的:
首先是javabean对象:

public class Bean {

    private int age;
    private String name;
    private boolean flag;

    public Bean() {
        super();
    }

    public Bean(int age, String name) {
        super();
        this.age = age;
        this.name = name;
    }

    public Bean(int age, boolean flag) {
        super();
        this.age = age;
        this.flag = flag;
    }

    public Bean(int age, String name, boolean flag) {
        super();
        this.age = age;
        this.name = name;
        this.flag = flag;
    }

    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public boolean isFlag() {
        return flag;
    }
    public void setFlag(boolean flag) {
        this.flag = flag;
    }
    @Override
    public String toString() {
        return "Bean [age=" + age + ", name=" + name + ", flag=" + flag + "]";
    }

}

然后是创建过程:

        Bean bean = new Bean(12,true,"小灯笼");

这样就得到了我们想要的bean对象实例。

3.使用Spring之后创建对象

在使用Spring之后,我们不仅仅可以使用普通方法创建对象,还可以通过依赖注入的方式得到我们想要的对象实例。

  • 创建一个Spring的配置文件beans.xml
    
    <bean id="beanByProperty" class="com.shi.springmvc.bean.Bean">
        
        <property name="age" value="12">property>
        <property name="name" value="李天水">property>
        <property name="flag" value="false">property>
    bean>

然后是获取过程:

        //创建 Spring 的 IOC 容器
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("/bean.xml");
        //从容器中获取 bean 的实例
        Bean bean = (Bean) ctx.getBean("beanByProperty");

我们发现,这里不再需要new了,我们只需要创建好配置文件,在一个称为IOC的容器中抓我们想要的对象即可,传统的资源查找方式要求组件向容器发起请求查找资源. 作为回应, 容器适时的返回资源. 而应用了 IOC 之后, 则是容器主动地将资源推送给它所管理的组件, 组件所要做的仅是选择一种合适的方式来接受资源. 这种行为也被称为查找的被动形式,其实本质上来说,这不仅是一个框架的使用,更是一种编程思想的转变。

4.上面我们使用的是属性注入的方式获取对象实例,下面我们使用构造器注入的方式来获取对象实例:

我们在bean.xml文件中添加:

    <bean id="beanByConstructor" class="com.shi.springmvc.bean.Bean">
        
        <constructor-arg value="15">constructor-arg>
        <constructor-arg value="华凤珊">constructor-arg>
        <constructor-arg value="true">constructor-arg>
    bean>

然后

        Bean bean = (Bean) ctx.getBean("beanByConstructor");

就可以获取到我们想要的对象实例了。

5.存在属性对象,构造方法参数不同的对象实例的获取方式

我们知道一个对象可以有多个构造方法,参数个数和类型肯定也都不一样,而一个对象中可能还包含有属性对象,那么我们如何处理呢?我们继续《Spring学习笔记<四> AOP 拦截器的基本实现》的项目基础上,再添加bean.java(上面已经给出)
BeanParent.java对象

public class BeanParent {

    private String country;
    private String language;
    private Bean bean;
    public String getCountry() {
        return country;
    }
    public void setCountry(String country) {
        this.country = country;
    }
    public String getLanguage() {
        return language;
    }
    public void setLanguage(String language) {
        this.language = language;
    }
    public Bean getBean() {
        return bean;
    }
    public void setBean(Bean bean) {
        this.bean = bean;
    }
    @Override
    public String toString() {
        return "BeanParent [country=" + country + ", language=" + language + ", bean=" + bean + "]";
    }

}

TestIOC.java文件(com.shi.springmvc.bean包下面)):


@Controller
public class TestIOC {

    private String SUCCESS = "success";

    //不实用Spring创建bean对象
    @RequestMapping("/createBean")
    private String createBean(){
        Bean bean = new Bean();
        bean.setAge(12);
        bean.setFlag(true);
        bean.setName("小灯笼");
        System.out.println(bean);
        return SUCCESS;
    }


    @RequestMapping("/getBeanByProperty")
    public String getBeanByProperty(){
        //创建 Spring 的 IOC 容器
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("/bean.xml");
        //从容器中获取 bean 的实例,
        //注意,这里的beanByProperty是在beans.xml中配置过的,getBean后的名字必须要和beans.xml中定义的id名称一致
        //否则无法获取该HelloWorld bean的实例
        Bean bean = (Bean) ctx.getBean("beanByProperty");
        System.out.println(bean);
        return SUCCESS;
    }

    @RequestMapping("/getBeanByConstructor")
    public String getBeanByConstructor(){
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("/bean.xml");
        Bean bean = (Bean) ctx.getBean("beanByConstructor");
        System.out.println(bean);
        return SUCCESS;
    }   

    @RequestMapping("/getBeanByConstructor01")
    public String getBeanByConstructor01(){
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("/bean.xml");
        Bean bean = (Bean) ctx.getBean("beanByConstructor01");
        System.out.println(bean);
        return SUCCESS;
    }   

    @RequestMapping("/getBeanByConstructor02")
    public String getBeanByConstructor02(){
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("/bean.xml");
        Bean bean = (Bean) ctx.getBean("beanByConstructor02");
        System.out.println(bean);
        return SUCCESS;
    }

    @RequestMapping("/getParentBeanByProperty01")
    public String getParentBeanByProperty01(){
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("/bean.xml");
        BeanParent beanParent = (BeanParent) ctx.getBean("beanParentByProp01");
        System.out.println(beanParent);
        return SUCCESS;
    }

    @RequestMapping("/getParentBeanByProperty02")
    public String getParentBeanByProperty02(){
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("/bean.xml");
        BeanParent beanParent = (BeanParent) ctx.getBean("beanParentByProp02");
        System.out.println(beanParent);
        return SUCCESS;
    }   

}

test_ioc.jsp文件(WebContent文件夹下面)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
"-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">


"Content-Type" content="text/html; charset=UTF-8">
创建bean对象



    "createBean">createBean
    

"getBeanByProperty">getBeanByProperty

getbeanByConstructor

"getBeanByConstructor01">getBeanByConstructor01

"getBeanByConstructor02">getBeanByConstructor02

"getParentBeanByProperty01">getParentBeanByProperty01

"getParentBeanByProperty02">getParentBeanByProperty02

bean.xml文件(src文件夹下面)


<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">


    
    <bean id="beanByProperty" class="com.shi.springmvc.bean.Bean">
        
        <property name="age" value="12">property>
        <property name="name" value="李天水">property>
        <property name="flag" value="false">property>
    bean>

    <bean id="beanByConstructor" class="com.shi.springmvc.bean.Bean">
        
        <constructor-arg value="15">constructor-arg>
        <constructor-arg value="华凤珊">constructor-arg>
        <constructor-arg value="true">constructor-arg>
    bean>

    <bean id="beanByConstructor01" class="com.shi.springmvc.bean.Bean">
        
        <constructor-arg value="15" index="0">constructor-arg>
        <constructor-arg value="华凤珊" index="1" type="String">constructor-arg>
    bean>

    <bean id="beanByConstructor02" class="com.shi.springmvc.bean.Bean">
        
        <constructor-arg value="15" index="0">constructor-arg>
        <constructor-arg value="true" index="1" type="boolean">constructor-arg>
    bean>

    <bean id="beanParentByProp01" class="com.shi.springmvc.bean.BeanParent">
        
        <property name="country" value="12">property>
        <property name="language" value="李天水">property>
        <property name="bean" ref="beanByProperty">property>
    bean>

    <bean id="beanParentByProp02" class="com.shi.springmvc.bean.BeanParent">
        
        <property name="country" value="12">property>
        <property name="language" value="李天水">property>
        <property name="bean">

            <bean class="com.shi.springmvc.bean.Bean">
                <constructor-arg value="15">constructor-arg>
                <constructor-arg value="华凤珊">constructor-arg>
                <constructor-arg value="true">constructor-arg>
            bean>

        property>
    bean>
beans>

上面的代码分别实现了:通过属性注入(getBeanByProperty),构造器注入(getBeanByConstructor),以及构造方法参数不同(getBeanByConstructor01和getBeanByConstructor02)来获取Bean对象的实例,以及对象属性中有子对象的BeanParent如何获取实例的两种方法(配置文件中使用ref和不实用ref)。

6.效果图:

我们可以看到,我们成功获取到了Bean和BeanParent的对象实例。

最后附上demo下载地址:戳我进入

你可能感兴趣的:(spring,Spring学习)