java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Spring Bean的配置细节

浅聊一下Spring中Bean的配置细节

作者:god23bin

我们知道,当写完一个普通的 Java 类后,想让 Spring IoC 容器在创建类的实例对象时使用构造方法完成实例对象的依赖注入,那么就需要在配置元数据中写好类的 Bean 定义,包括各种标签的属性。所以本文我们来说说这其中的配置细节,需要的朋友可以参考下

Bean 定义中的基本标签

property

property 标签:用于注入简单属性值,可以通过 name 属性指定属性名称,通过 value 属性指定属性值,或者通过 ref 属性指定引用其他 Bean。

<bean id="employee" class="cn.god23bin.demo.domain.entity.Employee">
    <property name="id" value="1" />
    <property name="name" value="god23bin" />
    <property name="department" ref="department" />
</bean>
<bean id="department" class="cn.god23bin.demo.domain.entity.Department">
    <property name="id" value="1" />
    <property name="name" value="JUST DO IT" />
</bean>

constructor

constructor 标签:使用构造方法参数值进行注入。通过 value 属性指定了参数的具体值,或通过 ref 属性指定了对其他 Bean 的引用。这样,在容器创建 Bean 实例时,会使用指定的参数值调用构造方法,实现构造方法注入。

<bean id="employee" class="cn.god23bin.demo.domain.entity.Employee">
    <constructor-arg value="1" />
    <constructor-arg value="god23bin" />
    <constructor-arg ref="department" />
</bean>
<bean id="department" class="cn.god23bin.demo.domain.entity.Department">
    <constructor-arg value="1" />
    <constructor-arg value="JUST DO IT" />
</bean>

list

list 标签:用于注入 List 集合类型的属性值,可以通过value 子标签指定元素的值,或者通过 ref 子标签指定引用其他 Bean。

<bean id="employee" class="cn.god23bin.demo.domain.entity.Employee">
    <property name="skills">
        <list>
            <value>Java</value>
            <value>Spring</value>
            <value>MySQL</value>
        </list>
    </property>
    <property name="departments">
        <list>
        	<ref bean="department" />
        </list>
    </property>
</bean>
<bean id="department" class="cn.god23bin.demo.domain.entity.Department">
    <constructor-arg value="1" />
    <constructor-arg value="JUST DO IT" />
</bean>

set

set 标签:用于注入 Set 集合类型的属性值,用法和 list 标签类似。

<bean id="employee" class="cn.god23bin.demo.domain.entity.Employee">
  <property name="setProperty">
    <set>
      <value>Value 1</value>
      <ref bean="bean1"/>
      <ref bean="bean2"/>
    </set>
  </property>
</bean>

map

map 标签:用于注入 Map 集合类型的属性值,可以通过 entry 子标签指定键值对,键可以通过 key 属性指定,值可以通过 value 属性指定,或者通过 ref 子标签指定引用其他Bean。

<bean id="employee" class="cn.god23bin.demo.domain.entity.Employee">
  <property name="mapProperty">
    <map>
      <entry key="key1" value="Value 1"/>
      <entry key="key2">
        <ref bean="bean1"/>
      </entry>
    </map>
  </property>
</bean>

props 标签:用于注入 Properties 类型的属性值,可以通过 prop 子标签指定键值对,键可以通过 key 属性指定,值可以通过 value 属性指定。

<bean id="employee" class="cn.god23bin.demo.domain.entity.Employee">
  <property name="propsProperty">
    <props>
      <prop key="key1">Value 1</prop>
      <prop key="key2">Value 2</prop>
    </props>
  </property>
</bean>

以上是 Spring XML 配置文件中 Bean 注入的常用标签和集合注入的标签。

depend-on 的使用

正常情况下,举个例子:

public class A {
    private B b;
    // 省略 getter 和 setter
}

B 这个 Bean 被写成是 A 的属性,也就是说,A 类依赖 B 类,这种正常的依赖关系下,我们在以 XML 为配置元数据的配置文件中,可以使用 ref 属性来指定 A 的依赖项是 B。

<bean id="a" class="cn.god23bin.demo.domain.model.A">
    <property name="b" ref="b" />
</bean>
<bean id="b" class="cn.god23bin.demo.domain.model.B"/>

这种依赖关系,是很明显的,一下子就能看出 A 是依赖 B 的,所以我们可以使用 ref 属性来指定依赖项,与此同时,这个依赖项会被注入到需要它的 Bean 中,这里就是 B 的对象被注入到 A 中作为 b 属性。

那么对于依赖关系不明显,但是又有依赖关系的时候,就可以使用 depend-on 属性。

比如有一个类 C,它是间接依赖 D 类的,也就是说 D 没有作为 C 的属性。此时,想要实例化 C,那么需要 D 先实例化好后,才能去实例化 C。

<bean /> 标签中的 depend-on 属性就能够做到这一点,让这种依赖关系不明显的,也能保证你在使用某个 Bean 时,该 Bean 的依赖项会先实例化。

<!-- 使用 depend-on 属性指定 C 这个 Bean 是依赖于 D 的 -->
<bean id="c" class="cn.god23bin.demo.domain.model.C" depend-on="d" />
<bean id="d" class="cn.god23bin.demo.domain.model.D" />

这样,在使用 C 时,是能够保证 C 的依赖项 D 是已经实例化好的。

如果有多个依赖项,那么可以使用有效的分隔符进行分割(英文逗号、英文分号或者空格):

<!-- 使用 depend-on 属性指定 C 这个 Bean 是依赖于 D 的 -->
<bean id="c" class="cn.god23bin.demo.domain.model.C" depend-on="d,another" />
<bean id="d" class="cn.god23bin.demo.domain.model.D" />
<bean id="another" class="cn.god23bin.demo.model.Another" />

同理,销毁对象的时候,在销毁 C 对象之前,D 就会被先销毁。

lazy-init 的使用

<bean /> 标签中的 lazy-init 属性是用来指定某个 Bean 是否开启懒加载的。

默认情况下,Bean 定义中这个属性默认值是 false,也就是说默认的 Bean 都不是懒加载的,当 Spring IoC 容器创建后,容器就会立即去创建并完全配置所有的单例作用域的 Bean。

如果我们想让某个 Bean 不在一开始就被实例化,那么就可以使用这个懒加载属性开启某个 Bean 的懒加载。懒加载的 Bean,只有在被第一次使用时,才会被实例化。

在以 XML 为配置元数据为例,直接使用 lazy-init 属性,设置该属性为 true 就 OK。

<bean id="lazyBean" class="cn.god23bin.demo.domain.model.LazyBean" lazy-init="true" />

当然,如果这个懒加载的 Bean 被其他没有懒加载的单例 Bean 给引用了,那么这个懒加载的 Bean 也会在容器创建后被容器所创建,因为容器必须确保单例 Bean 的依赖项都被实例化了。

自动注入依赖项

Spring 支持 Bean 之间依赖关系的自动注入。 它能根据 ApplicationContext 的内容帮我们处理 Bean 之间的依赖关系,这样我们就可以不用手动在配置元数据中指定 Bean 之间的依赖关系。

网上有很多博客把「自动注入」说成「自动装配」的,在我看来,这是两回事,实际上从它们的英文名来看,就是两回事。

说到自动装配(Auto Configuration),一般都是联系到 Spring Boot 的,因为它的特点就是开箱即用,省去大量的配置,而之所以能省去大量的配置,就得益于它的自动装配。而自动注入(Autowiring Collaborator)是指自动注入协作者,换句话说,指 Bean 之间的依赖项 Spring 能帮你去注入。

自动注入的优点

以 XML 作为配置元数据的情况下,我们可以使用 <bean /> 标签中的 autowire 属性来指定自动注入的模式。

3 种自动注入的模式

默认没有自动注入,这就是最开始学习的写法,Bean 的依赖项需要用 ref 属性来指定。

<bean id="employee" class="cn.god23bin.demo.domain.entity.Employee" autowire="byName">
    <!-- 属性 -->
</bean>
<bean id="employee" class="cn.god23bin.demo.domain.entity.Employee" autowire="byType">
    <!-- 属性 -->
</bean>
<bean id="employee" class="cn.god23bin.demo.domain.entity.Employee" autowire="constructor">
    <!-- 构造函数参数 -->
</bean>

需要注意的是,自动注入只对那些具有依赖关系的 Bean 起作用,而不是所有的 Bean。因此,在配置 Bean 的时候,需要确保被注入的属性在其他 Bean 中是存在的。

自动注入的限制和缺点

对于自动注入匹配到了多个 Bean,有以下解决方案:

这几个使用注解实现自动注入的,在后面的文章中再讲。

总结

我们总结一下,关于 Spring 中 Bean 的配置与依赖注入的重要内容。

以上就是浅聊一下Spring中Bean的配置细节的详细内容,更多关于Spring Bean的配置细节的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文