Spring IOC 简单类型的注入方式

 首先我们需要创建一个 bean

public class Person {                                                                                      
    private String name;                                                                                
    private String gender;                                                                              
    private Integer age;                                                                                  
    private String email;                                                                                 
    // get/set 方法...

    // toString ...                                                                                             
}                                                                                              

通过配置文件实现

 我们需要先创建一个spring配置文件,然后在配置文件中配置我们的 需要注入的 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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

</beans>       

 创建完成之后,我们就可以开始配置我们的 bean 了

属性注入方式
通过set 方式注入
    <bean id="person01" class="spring.bean.Person">
        <property name="name" value="张三"></property>
        <property name="age" value="18"></property>
        <property name="gender" value="male"></property>
        <property name="email" value="123@qq.com"></property>
    </bean>           
  • class:填写需要注册组件的全限定类名
  • id:标识这个对象的唯一标识,后面我们需要通过这个唯一表示获取实例化对象

 在 bean 标签里面,我们可以通过 property 标签配置 bean 的属性。

  • name:属性名
  • value: 属性值

 接下来,我们就可以使用开始测试,看注入是否成功

    @Test
    public void test() {
        ApplicationContext context = new ClassPathXmlApplicationContext("ioc.xml");
        Person bean = (Person) context.getBean("person01");
        System.out.println(bean);
    }            

Person{name=‘张三’, gender=‘male’, age=18, email=‘123@qq.com’}

 ClassPathXmlApplicationContext表示当前应用的 xml 配置文件在 classpath下。还有一种方式是使用 FileSystemXmlApplicationContext,传入的是磁盘中配置文件的路径,但是我们一般都不会使用这个。

下面,让我们想一下,我们得到的组件对象是由谁来创建的呢?这个不用多想,就知道时由 ioc 容器创建的。那么是什么时候开始创建的呢?是单例的还是多例的呢?我们不妨来做一个实验。

我们在bean 的构造函数中加上一个打印语句

public class Person {
    ...
    
    public Person() {
        System.out.println("Person 被创建了");
    }

    ...
}

    @Test
    public void test() {

    System.out.println("容器创建前");
    ApplicationContext context = new ClassPathXmlApplicationContext("ioc.xml");

    System.out.println("对象获取前");
    Person bean = (Person) context.getBean("person01");
    Person bean2 = (Person) context.getBean("person01");

    System.out.println("对象获取后");
    System.out.println(bean);
    System.out.println(bean2);
    System.out.println(bean == bean2);
    }

容器创建前

Person 被创建了

对象获取前

对象获取后

Person{name=‘张三’, gender=‘male’, age=18, email=‘123@qq.com’}

Person{name=‘张三’, gender=‘male’, age=18, email=‘123@qq.com’}

true

 由输出结果可以看出,对象是在容器创建的时候完成的。而且只打印了一句 “Person 被创建了”,且最后获取的两个对象是同一个对象,所以 ioc 容器中的组件对象是单例的。

 那么,如果我们想要让 ioc 容器创建多实例对象怎么办呢?我们可以在 bean 标签中加上 scope属性,其值有四个:

  • prototype: 多实例的。容器启动时不会创建bean,在获取时才创建
  • singleton: 单实例的。容器启动时创建bean(默认)
  • request: 在web环境下,同一个请求下创建一个 bean 实例
  • session: 在web环境下,同一次会话下创建一个 bean 实例

 接下来,我们再想一下,ioc 容器是如何给 组件对象的属性赋值的呢?ioc 容器在创建这个组件对象时,(property)会利用setter方法为 JavaBean的属性进行赋值。不信,我们可以再次实验一下,我们在 setter方法中添加一句打印语句,然后运行一下我们的第一个 test 用例

    public void setName(String name) {
        System.out.println("setName..." + name);
        this.name = name;
    }

Person 被创建了

setName…张三

Person{name=‘张三’, gender=‘male’, age=18, email=‘123@qq.com’}

 这样,我们就有充分的证据证明 ioc 容器在创建组件对象时,(property)会利用setter方法为 JavaBean的属性进行赋值。
需要注意的是 JavaBean的属性名由 getter/setter 方法决定

 其实,getBean()中除了可以传入组件的 id 外,还可以传入Person.class形式的参数。这种方式的好处是你不需要将获得的对象进行强转,但是如果 ioc 容器里面管理了两个 还可以传入Person,它就不知道你想要得到的是哪个对象,从而报错: “No qualifying bean of type[xxx] is defined:expected single matching bean but found 2:…”。想要解决这个问题,你可以传入两个参数:id 和 Person.class。

通过构造器注入
    <bean id="person02" class="spring.bean.Person">
        <constructor-arg name="name" value="张三"></constructor-arg>
        <constructor-arg name="age" value="18"></constructor-arg>
        <constructor-arg name="gender" value="male"></constructor-arg>
        <constructor-arg name="email" value="123@qq.com"></constructor-arg>
    </bean>

constructor-arg:

  • name:属性名
  • value:属性值

 这种通过有参构造器的方法也可以为 ioc 的组件对象赋值。但是前提是你的 bean 中需要写构造器,而且如果你只写了一个带 4 个参数的构造器,你就必须在 标签中为四个属性都赋值。

注意,name属性可以省略,但是为参数赋值的顺序必须与构造器中的顺序一样,除非你使用 index 为参数指定索引。如果你有两个参数相同的构造器,其赋值方式就有一定的随机性了。这时你需要使用 type 来指定参数的类型。

通过 p 名称空间注入
    <bean id="person03" class="spring.bean.Person"
    p:age="18" p:email="123@qq.com" p:name="张三" p:gender="male"
    >

在 xml 中,名称空间是用来防止标签重复的。让我们来假想以下如果一个类中有另外的一个对象属性,而这个对象里面有一个与当前类同名的属性,那么我们该如何配置这个类呢?这个时候就可以用我们的名称空间来标识他们了。

在是使用 p 名称空间之前,我们需要在 xml 中加入这样一段约束:

xmlns:p="http://www.springframework.org/schema/p"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值