Spring Bean 初步

通过前一章内容我们看到,Bean 本质上就是我们通过配置文件,去指导 Spring 进行初始化产生的对象。实际上,Bean 在 Spring 中还有很多属性,在这一章我们主要关注和对象创建有关的内容,其中很重要的一点,就是对象的依赖。

在真正的业务中,对象之间会形成复杂的依赖关系。在 Spring 的 Bean 配置中,我们可以描述出这种依赖关系,Spring 会根据依赖关系,正确地进行 Bean 的初始化。

Constructor 注入

首先第一种依赖注入的方式,就是通过 Constructor 进行注入。下面通过一个例子展示一下。我们将上一章的 Service 拆分出一个 model 类 Person:

  1. package com.skyline.model;
  2. public class Person {
  3. private String name;
  4. public String getName() {
  5. return name;
  6. }
  7. public void setName(String name) {
  8. this.name = name;
  9. }
  10. }

和一个依赖 Person 的 Service 类:

  1. package com.skyline.service;
  2. import com.skyline.model.Person;
  3. public class MyServiceImpl implements MyService {
  4. private Person person;
  5. public MyServiceImpl(Person person)
  6. {
  7. this.person = person;
  8. }
  9. @Override
  10. public String sayHello() {
  11. return "Hello " + this.person.getName();
  12. }
  13. }

可以看到,Service 初始化时,在 Constructor 中需要一个 Person 的实例。为了让代码正常工作,我们需要更改 Bean 的配置:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans.xsd">
  6. <bean id="aPerson" class="com.skyline.model.Person">
  7. <property name="name" value="Chester"/>
  8. </bean>
  9. <bean id="myService" class="com.skyline.service.MyServiceImpl">
  10. <constructor-arg ref="aPerson"/>
  11. </bean>
  12. </beans>

通过这样的方式,Spring 会先初始化 aPerson,然后使用它初始化 myService。运行代码,结果和之前是一样的。

此外,对于不是自定义类的普通参数,也可以使用 XML 进行注入,例如我们更改 Serivce 类,加入 greeting 参数:

  1. public class MyServiceImpl implements MyService {
  2. private Person person;
  3. private String greeting;
  4. public MyServiceImpl(Person person, String greeting)
  5. {
  6. this.person = person;
  7. this.greeting = greeting;
  8. }
  9. @Override
  10. public String sayHello() {
  11. return this.greeting + " " + this.person.getName();
  12. }
  13. }

修改 XML 配置如下:

  1. <bean id="myService" class="com.skyline.service.MyServiceImpl">
  2. <constructor-arg ref="aPerson"/>
  3. <constructor-arg type="java.lang.String" value="Hello"/>
  4. </bean>

运行程序,仍然可以打印出预期结果。

Setter 注入

另一种依赖注入方式,是通过 Setter,这种方式类似于初始化 Bean 的参数。仍然用一个例子,我们把 Service 改成下面这样:

  1. public class MyServiceImpl implements MyService {
  2. private Person person;
  3. private String greeting;
  4. public Person getPerson() {
  5. return person;
  6. }
  7. public void setPerson(Person person) {
  8. this.person = person;
  9. }
  10. public String getGreeting() {
  11. return greeting;
  12. }
  13. public void setGreeting(String greeting) {
  14. this.greeting = greeting;
  15. }
  16. @Override
  17. public String sayHello() {
  18. return this.greeting + " " + this.person.getName();
  19. }
  20. }

与之对应的,修改 XML 配置文件:

  1. <bean id="aPerson" class="com.skyline.model.Person">
  2. <property name="name" value="Chester"/>
  3. </bean>
  4. <bean id="myService" class="com.skyline.service.MyServiceImpl">
  5. <property name="person" ref="aPerson"/>
  6. <property name="greeting" value="Hello"/>
  7. </bean>

运行程序,结果保持不变。