spring学习(二)Spring 中的 Bean 配置

来源:互联网 发布:java编程实例1200例 编辑:程序博客网 时间:2024/06/04 19:06

IOC 和 DI

  • IOC(Inversion of Control):其思想是反转资源获取的方向. 传统的资源查找方式要求组件向容器发起请求查找资源。
    作为回应, 容器适时的返回资源. 而应用了 IOC 之后, 则是容器主动地将资源推送给它所管理的组件,组件所要做的仅是选择一种合适的方式来接受资源. 这种行为也被称为查找的被动形式。
  • DI(Dependency Injection) — IOC 的另一种表述方式:即组件以一些预先定义好的方式(例如: setter方法)接受来自如容器的资源注入. 相对于 IOC 而言,这种表述更直接。

介绍IOC和DI这两个概念是用来可以更好的去理解spring如何去创建对象的,在上一篇文章中使用spring获取到了ApplicationContext对象后,可以直接用这个对象去实例化HelloWorld对象,而不需要去使用new来创建一个对象。那么spring是如何去创建对象的,前面提到过ApplicationContext是Spring的IOC容器,在这个容器中spring为我们去管理在配置文件中我们配置的哪些类的对象,需要使用时向spring中获取这个对象,对象使用完毕后spring自动去回收这个对象。

在 Spring 的 IOC 容器里配置 Bean

在 xml 文件中通过 bean 节点来配置 bean

<!--通过全类名的方式类配置bean--><bean id="helloworld" class="com.iflytek.test.bean.HelloWorld"></bean>

id:Bean 的名称。
- 在 IOC 容器中必须是唯一的 。
- 若 id 没有指定,Spring 自动将权限定性类名作为 Bean 的名字。
- id可以指定多个名字,名字之间可用逗号、分号、或空格分隔。

Spring 容器

在 Spring IOC 容器读取 Bean 配置创建 Bean 实例之前, 必须对它进行实例化. 只有在容器实例化后, 才可以从 IOC 容器里获取 Bean 实例并使用.。
Spring 提供了两种类型的 IOC 容器实现.
- BeanFactory: IOC 容器的基本实现.。
- ApplicationContext: 提供了更多的高级特性. 是BeanFactory 的子接口.。
其中BeanFactory 是 Spring 框架的基础设施,面向 Spring本身; ApplicationContext 面向使用 Spring 框架的开发者,几乎所有的应用场合都直接使ApplicationContext 而非底层的 BeanFactory 无论使用何种方式, 配置文件时相同的。

ApplicationContext

1.ApplicationContext的继承结构:
这里写图片描述
2.ApplicationContext 的主要实现类:
- ClassPathXmlApplicationContext:从类路径下加载配置文件。
- FileSystemXmlApplicationContext: 从文件系统中加载配置文件。
3.ConfigurableApplicationContext 扩展于 ApplicationContext,新增加两个主要方法:refresh() 和 close(), 让 ApplicationContext 具有启动、刷新和关闭上下文的能力。
4.ApplicationContext 在初始化上下文时就实例化所有单例的 Bean。

从 IOC 容器中获取 Bean

这里写图片描述
调用 ApplicationContext 的 getBean(String) 方法,其中传入的参数是在配置文件中配置bean时声明的id。也可以调用getBean(Class) 方法,在使用该方法获取bean的时候需要注意,如过在配置文件中声明的同一个类有配置2个bean,那么spring是无法知道你是要获取哪一个bean的(当然一般情况下也不会出现这种配置两次的情况)。

依赖注入的方式

Spring 支持 3 种依赖注入的方式
- 属性注入
- 构造器注入
- 工厂方法注入(很少使用,不推荐)

属性注入

-属性注入即通过 setter 方法注入Bean 的属性值或依赖的对象
-属性注入使用 元素, 使用 name 属性指定 Bean 的属性名称,value 属性或 子节点指定属性值
-属性注入是实际应用中最常用的注入方式

<!--通过全类名的方式类配置bean--><bean id="helloworld" class="com.iflytek.test.bean.HelloWorld">    <!-- 为属性赋值 -->    <!-- 通过属性注入: 通过 setter 方法注入属性值 -->    <property name="name" value="tom"></property></bean>

这种注入方式是之前的例子中写过的

构造方法注入

通过构造方法注入Bean 的属性值或依赖的对象,它保证了 Bean 实例在实例化后就可以使用。
构造器注入在 元素里声明属性, 中没有 name 属性
将属性注入注释掉,使用构造器注入来看效果

    <!-- 通过构造器注入属性值 -->    <bean id="helloworld" class="com.iflytek.test.bean.HelloWorld">             <!--<property name="name" value="tom"></property>  -->        <!-- 要求: 在 Bean 中必须有对应的构造器.  -->        <constructor-arg value="lily"></constructor-arg>    </bean>

对用的HelloWorld实体类

public class HelloWorld {    private String name;    //在无参的构造函数中打印一条消息    public HelloWorld() {        super();        System.out.println("Constructed is used...");    }    public HelloWorld(String name) {        super();        this.name = name;    }    public String getName() {        return name;    }//  //在set方法中打印信息//  public void setName(String name) {//      System.out.println("after name:"+name);//      this.name = name;//      System.out.println("before name:"+name);//  }//      public void hello(){        System.out.println("hello:"+name);    }}

控制台打印的结果:
这里写图片描述
使用构造器注入属性值的时候需要注意
写一个新的实体类

public class Car {    private int maxSpeed;    private String name;    private float price;    public Car(int maxSpeed, String name, float price) {        super();        this.maxSpeed = maxSpeed;        this.name = name;        this.price = price;    }    @Override    public String toString() {        return "Car :maxSpeed=" + maxSpeed + ", name=" + name + ", price=" + price ;    }   }
    <!-- 若一个 bean 有多个构造器, 如何通过构造器来为 bean 的属性赋值 -->    <!-- 可以根据 index 和 value 进行更加精确的定位. (了解) -->    <bean id="car" class="com.iflytek.test.bean.Car">               <constructor-arg>            <value>10</value>        </constructor-arg>        <constructor-arg value="宝马"></constructor-arg>        <constructor-arg value="15.5"></constructor-arg>    </bean>    <bean id="car1" class="com.iflytek.test.bean.Car">          <constructor-arg value="15.5" type="float"></constructor-arg>           <constructor-arg index="0">            <value>10</value>        </constructor-arg>        <!-- 若字面值中包含特殊字符, 则可以使用 DCDATA 来进行赋值. (了解) -->        <constructor-arg index="1">            <value><![CDATA[宝马@__@]]></value>        </constructor-arg>          </bean>

控制台打印的结果:
这里写图片描述

###字面值

  • 字面值:可用字符串表示的值,可以通过 元素标签或 value 属性进行注入。
  • 基本数据类型及其封装类、String等类型都可以采取字面值注入的方式
  • 若字面值中包含特殊字符,可以使用
0 0