依赖注入

依赖注入

  • 依赖:指Bean对象的创建依赖于容器。

  • 注入:指Bean对象所依赖的资源,有容器来设置和装配,注入某个对象所需要的外部资源(包括对象、资源、常量数据)

三种依赖注入方式

1. 构造器注入

就是前面案例中的通过有参构造器来实现构造器注入。

2. Set注入

要求被注入的对象,必须有set方法,如果属性是boolean类型,没有set方法,是is。

测试pojo类:

  1. Student.java

    package com.aishimin.pojo;
    ​
    import java.util.*;
    ​
    public class Student {
        private String name;
        private Address address;
        private String[] books;
        private List<String> hobbys;
        private Map<String,String> card;
        private Set<String> games;
        private Properties info;
    ​
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", address=" + address.toString()+
                    ", books=" + Arrays.toString(books) +
                    ", hobbys=" + hobbys +
                    ", card=" + card +
                    ", games=" + games +
                    ", info=" + info +
                    '}';
        }
    ​
        public String getName() {
            return name;
        }
    ​
        public void setName(String name) {
            this.name = name;
        }
    ​
        public Address getAddress() {
            return address;
        }
    ​
        public void setAddress(Address address) {
            this.address = address;
        }
    ​
        public String[] getBooks() {
            return books;
        }
    ​
        public void setBooks(String[] books) {
            this.books = books;
        }
    ​
        public List<String> getHobbys() {
            return hobbys;
        }
    ​
        public void setHobbys(List<String> hobbys) {
            this.hobbys = hobbys;
        }
    ​
        public Map<String, String> getCard() {
            return card;
        }
    ​
        public void setCard(Map<String, String> card) {
            this.card = card;
        }
    ​
        public Set<String> getGames() {
            return games;
        }
    ​
        public void setGames(Set<String> games) {
            this.games = games;
        }
    ​
        public Properties getInfo() {
            return info;
        }
    ​
        public void setInfo(Properties info) {
            this.info = info;
        }
    }
  2. Address.java

    package com.aishimin.pojo;
    ​
    public class Address {
        private String address;
    ​
        @Override
        public String toString() {
            return "Address{" +
                    "address='" + address + '\'' +
                    '}';
        }
    ​
        public String getAddress() {
            return address;
        }
    ​
        public void setAddress(String address) {
            this.address = address;
        }
    }

     

  1. 常量注入

    <property name="name" value="小明"/>
  2. Bean注入

    <bean id="address" class="com.aishimin.pojo.Address">
        <property name="address" value="郑州"/>
    </bean>
         
        <property name="address" ref="address"/>
  3. 数组注入

    <property name="books">
        <array>
            <value>三国演义</value>
            <value>西游记</value>
            <value>水浒传</value>
            <value>红楼梦</value>
        </array>
    </property>
  4. List注入

    <property name="hobbys">
        <list>
            <value>听歌</value>
            <value>爬山</value>
            <value>看电影</value>
        </list>
    </property>
  5. Map注入

    <property name="card">
        <map>
            <entry key="中国邮政" value="123213321321213"/>
            <entry key="工商银行" value="789897789456456"/>
        </map>
    </property>
  6. set注入

    <property name="games">
        <set>
            <value>英雄联盟</value>
            <value>王者荣耀</value>
            <value>穿越火线</value>
        </set>
    </property>
  7. Properties注入

    <property name="info">
        <props>
            <prop key="学号">20201212</prop>
            <prop key="性别"></prop>
            <prop key="年龄">12</prop>
        </props>
    </property>
  1. 测试结果

3. p命名和c命名注入

  1. p命名空间需要现在头文件中加入约束文件

    //导入约束文件
    xmlns:p="http://www.springframework.org/schema/p"
    ​
        <bean id="user" class="com.aishimin.pojo.User"
              p:name="小明" p:age="23">
        </bean>
  1. c命名空间注入需要先在头文件中加入约束文件

    //导入约束文件
    xmlns:c="http://www.springframework.org/schema/c"
    ​
    <bean id="user" class="com.aishimin.pojo.User"
        c:name="小胡" c:age="22"
    ></bean>
    ​
    或
    ​
     <bean id="user" class="com.aishimin.pojo.User"
        c:_0="嘻嘻嘻" c:_1="22"
    ></bean>

    注:使用c命名空间需要利用构造器,即需要在pojo类中加入构造方法

Bean的作用域

在Spring中,组成应用程序的主体及由Spring Ioc容器所管理的对象,被称为bean。简单来讲,bean就是由Ioc容器初始化、装配及管理的对象。

request和session的作用域仅在基于web的应用中使用,只能在基于web的Spring ApplicationContext环境。

Singleton

如果一个bean的作用域是Singleton,在Ioc容器中只会存在一个共享的bean实例,所有对bean的请求,只要id与该bean定义相匹配。则只会返回bean的同一实例。Singleton是单例类型,在创建容器是就同时自动创建了一个bean对象,不管是否使用都存在于Ioc容器中。

测试:

<bean id="user" class="com.aishimin.pojo.User" scope="singleton"
      c:name="小明" c:age="22">
</bean>
public class MyTest {
    @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        User user = context.getBean("user", User.class);
        User user1 = context.getBean("user",User.class);
        System.out.println(user==user1);
    }
}
​
运行结果为:true

Prototype

当一个bean的作用域为Prototype时,表示一个bean定义对应多个对象实例。Prototype作用域的bean会导致在每次对该bean请求时都会创建一个新的bean实例。Prototype是原型类型,在我们创建容器时并没有实例化,而是当我们获取bean对象时才会去创建一个对象,同时我们每一次获取的对象都不是同一个对象。

根据经验,对于有状态的bean应当使用Prototype作用域,而对于无状态的bean应该使用singleton作用域。

测试:

<bean id="user" class="com.aishimin.pojo.User" scope="prototype"
      c:name="小明" c:age="22">
</bean>
public class MyTest {
    @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        User user = context.getBean("user", User.class);
        User user1 = context.getBean("user",User.class);
        System.out.println(user==user1);
    }
}
​
运行结果为:false

Request

当一个bean的作用域为Request,表示在一次HTTP请求中,一个bean定义对应一个实例;即每个HTTP请求都会有各自的bean实例,它们依据某个bean定义创建而成。

 <bean id="loginAction"class=cn.csdn.LoginAction" scope="request"/>

针对每次HTTP请求,Spring容器会根据 loginAction bean的定义创建一个全新的LoginAction bean实例,且该loginAction bean实例仅在当前HTTP request内有效。

因此可以根据需要放心的更改所建实例的内部状态,而其他请求中根据loginAction bean定义创建的实例,将不会看到这些特定于某个请求的状态变化。当处理请求结束,request作用域的bean实例将被销毁。

Session

当一个bean的作用域为Session,表示在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。考虑下面bean定义:

<bean id="userPreferences"class="com.foo.UserPreferences"scope="session"/>

针对某个HTTP Session,Spring容器会根据userPreferences bean定义创建一个全新的userPreferences bean实例,且该userPreferences bean仅在当前HTTP Session内有效。与request作用域一样,可以根据需要放心的更改所创建实例的内部状态,而别的HTTP Session中根据userPreferences创建的实例,将不会看到这些特定于某个HTTP Session的状态变化。当HTTP Session最终被废弃的时候,在该HTTP Session作用域内的bean也会被废弃掉。

posted @ 2021-02-23 13:27  aishimin  阅读(51)  评论(0)    收藏  举报