【Spring】(3.4)依赖注入(基于setter)

【Spring】(3.4)依赖注入(基于setter)

一、基于setter的依赖注入

项目结构

在这里插入图片描述
创建一个用户类,只有一个无参构造器。

一定要生成set方法!因为property标签进行注入时,使用的是setXxx()方法进行注入的。所以该文章标题取名为“依赖注入(基于setter)”。

public class User {
    private String name;

    public User() {
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

设置配置文件。

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 第一种,使用value属性注入 -->
    <bean id="user1" class="com.shengjava.pojo.User">
        <property name="name" value="长生"/>
    </bean>
    <!-- 第二种,property标签下的ref引用注入(ref的值为其他bean的id) -->
    <bean id="user2" class="com.shengjava.pojo.User">
        <property name="name">
            <ref bean="str"/>
        </property>
    </bean>
    <bean id="str" class="java.lang.String">
        <constructor-arg type="java.lang.String" value="长生"/>
    </bean>

</beans>

编写测试类

public class UserTest {
    @Test
    public static void main(String[] args) {
        // create and configure beans(现在我们的对象都是Spring进行管理了,我们可以去Spring的容器ApplicationContext中获取。context:上下文、环境的意思)
        ApplicationContext context = new ClassPathXmlApplicationContext("pojos.xml");

        // retrieve configured instance(从上下文context中获取对象)
        User user1 = context.getBean("user1", User.class);
        User user2 = context.getBean("user2", User.class);
        System.out.println(user1);
        System.out.println(user2);

    }
}

输出

User{name='长生'}
User{name='长生'}

更多依赖注入例子,请查看:
Examples of Dependency Injection

二、注入复杂类型

依赖注入可以注入多种类型如:

  • 直接值(或字面量,上面xml中的第一种方式)
  • ref引用其他bean(上面xml中的第二种方式)
  • 内部的bean
  • 数组
  • 集合
  • 空字符串和null
  • p-namespace
  • c-namespace
  • 复合属性名

上面案例中,已经演示了两种类型的注入:1.直接值。2.ref引用其他bean

接下来做一个复杂类型的注入案例。

项目结构:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aANrYMaa-1586069559788)(BE908BF815B5469CAB6B06D04F352F64)]

创建地址类

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;
    }
}

创建学生类

public class Student {
    private String name;
    /** 现住址 */
    private Address address;
    /** 籍贯 */
    private Address nativePlace;
    private String[] books;
    private List<String> hobbies;
    private Map<String, String> card;
    private Set<String> games;
    private Properties info;
    private String wife;

    @Override
    public String toString() {
        return "Student{" +
                " \nname='" + name + '\'' +
                ", \naddress=" + address +
                ", \nnativePlace=" + nativePlace +
                ", \nbooks=" + Arrays.toString(books) +
                ", \nhobbies=" + hobbies +
                ", \ncard=" + card +
                ", \ngames=" + games +
                ", \ninfo=" + info +
                ", \nwife='" + wife + '\'' +
                '}';
    }

    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 Address getNativePlace() {
        return nativePlace;
    }

    public void setNativePlace(Address nativePlace) {
        this.nativePlace = nativePlace;
    }

    public String[] getBooks() {
        return books;
    }

    public void setBooks(String[] books) {
        this.books = books;
    }

    public List<String> getHobbies() {
        return hobbies;
    }

    public void setHobbies(List<String> hobbies) {
        this.hobbies = hobbies;
    }

    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;
    }

    public String getWife() {
        return wife;
    }

    public void setWife(String wife) {
        this.wife = wife;
    }
}

设置studentBeans.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 地址bean -->
    <bean id="address" class="com.shengjava.pojo.Address">
        <property name="address" value="中国浙江"></property>
    </bean>
    <!-- 学生bean -->
    <bean id="student" class="com.shengjava.pojo.Student">
        <!-- 注入直接量 -->
        <property name="name" value="张三"/>
        <!-- 注入其他bean -->
        <property name="address">
            <ref bean="address"/>
        </property>
        <!-- 注入内部bean -->
        <property name="nativePlace">
            <bean class="com.shengjava.pojo.Address">
                <property name="address" value="中国浙江"></property>
            </bean>
        </property>
        <!-- 注入数组 -->
        <property name="books">
            <array>
                <value>三体</value>
                <value>三国志</value>
                <value>三国演义</value>
            </array>
        </property>
        <!-- 注入集合 -->
        <property name="hobbies">
            <!-- List -->
            <list>
                <value>吉他</value>
                <value>篮球</value>
                <value>街舞</value>
            </list>
        </property>
        <property name="card">
            <!-- map -->
            <map>
                <entry key="中国银行" value="111...111"/>
                <entry key="农业银行" value="222...222"/>
                <entry key="建设银行" value="333...333"/>
            </map>
        </property>
        <property name="games">
            <!-- set -->
            <set>
                <value>王者荣耀</value>
                <value>绝地求生</value>
            </set>
        </property>
        <property name="info">
            <!-- Properties -->
            <props>
                <prop key="email">123@qq.com</prop>
                <prop key="phone">188xxxx8888</prop>
            </props>
        </property>
        <property name="wife">
            <!-- 注入值为null -->
            <null/>
        </property>
    </bean>
</beans>

编写测试类

public class StudentTest {
    public static void main(String[] args) {
        // 获取context
        ApplicationContext context = new ClassPathXmlApplicationContext("studentBeans.xml");
        // 获取对象
        Student student = context.getBean("student", Student.class);
        System.out.println(student);
    }
}

输出

Student{ 
name='张三', 
address=Address{address='中国浙江'}, 
nativePlace=Address{address='中国浙江'}, 
books=[三体, 三国志, 三国演义], 
hobbies=[吉他, 篮球, 街舞], 
card={中国银行=111...111, 农业银行=222...222, 建设银行=333...333}, 
games=[王者荣耀, 绝地求生], 
info={phone=188xxxx8888, email=123@qq.com}, 
wife='null'}

以上就是复杂类型注入,详细参考自:1.4.2. Dependencies and Configuration in Detail