Configuring Beans in the Spring IoC Container

Configuring Beans in the Spring IoC Container

这本书对spring bean的配置比较全面。

注:配置类似

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

的时候,xsd的版本号不要带,至于为什么,参考以前转载的老外博客。

Problem

Spring offers a powerful IoC container to manage the beans that make up an application. To utilize the

container services, you have to configure your beans to run in the Spring IoC container.

Solution

You can configure your beans in the Spring IoC container through XML files, properties files,

annotations, or even APIs.

Spring allows you to configure your beans in one or more bean configuration files. For a

simple application, you can simply centralize your beans in a single configuration file. But for a large

application with a lot of beans, you should separate them in multiple configuration files according to

their functionalities. One useful division is by the architectural layer that a given context services.

How It Works

Suppose that you are going to develop an application for generating sequence numbers. In this

application, there may be many series of sequence numbers to generate for different purposes. Each

one of them will have its own prefix, suffix, and initial value. So, you have to create and maintain

multiple generator instances in your application.

Creating the Bean Class

In accordance with the requirements, you create the SequenceGenerator class that has three

properties_prefix, suffix, and initial_that can be injected via setter methods or a constructor. The

private field counter is for storing the current numeric value of this generator. Each time you call the

getSequence() method on a generator instance, you will get the last sequence number with the prefix

and suffix joined. You declare this method as synchronized to make it thread-safe.

package com.apress.springenterpriserecipes.sequence;
public class SequenceGenerator {
private String prefix;
private String suffix;
private int initial;
private int counter;
public SequenceGenerator() {}
public SequenceGenerator(String prefix, String suffix, int initial) {
this.prefix = prefix;
this.suffix = suffix;
this.initial = initial;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public void setSuffix(String suffix) {
this.suffix = suffix;
}
public void setInitial(int initial) {
this.initial = initial;
}
public synchronized String getSequence() {
StringBuffer buffer = new StringBuffer();
buffer.append(prefix);
buffer.append(initial + counter++);
buffer.append(suffix);
return buffer.toString();
}
}

As you see, this SequenceGenerator class can be configured by getters/setters or by the constructor.

When configuring them with the container, this is called constructor injection and setter injection.

Creating the Bean Configuration File

To declare beans in the Spring IoC container via XML, you first have to create an XML bean

configuration file with an appropriate name, such as beans.xml. You can put this file in the root

of the classpath for easier testing within an IDE.

The Spring configuration XML allows you to use custom tags from different schemas (tx, jndi, jee,

and so on) to make the bean configuration simpler and clearer. Here’s an example of the simplest XML

configuration possible.

<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-3.0.xsd">
...
</beans>

Declaring Beans in the Bean Configuration File

Each bean should provide a unique name or id and a fully qualified class name for the Spring IoC

container to instantiate it. For each bean property of simple type (e.g., String and other primitive types),

you can specify a <value> element for it. Spring will attempt to convert your value into the declaring type

of this property. To configure a property via setter injection, you use the <property> element and specify

the property name in its name attribute. A <property> requires that the bean contain a corresponding

setter method.

<bean name="sequenceGenerator"
class="com.apress.springenterpriserecipes.sequence.SequenceGenerator">
<property name="prefix">
<value>30</value>
</property>
<property name="suffix">
<value>A</value>
</property>
<property name="initial">
<value>100000</value>
</property>
</bean>

You can also configure bean properties via constructor injection by declaring them in the

<constructor-arg>
elements. There’s not a
name
attribute in
<constructor-arg>
because constructor

arguments are position-based.

<bean name="sequenceGenerator"
class="com.apress.springenterpriserecipes.sequence.SequenceGenerator">
<constructor-arg>
<value>30</value>
</constructor-arg>
<constructor-arg>
<value>A</value>
</constructor-arg>
<constructor-arg>
<value>100000</value>
</constructor-arg>
</bean>

In the Spring IoC container, each bean’s name should be unique, although duplicate names are

allowed for overriding bean declaration if more than one context is loaded. A bean’s name can be

defined by the name
attribute of the <bean>
element. Actually, there’s a preferred way of identifying a

bean: through the standard XML
id attribute, whose purpose is to identify an element within an XML

document. In this way, if your text editor is XML-aware, it can help to validate each bean’s uniqueness at

design time.

<bean id="sequenceGenerator"
class="com.apress.springenterpriserecipes.sequence.SequenceGenerator">
...
</bean>

However, XML has restrictions on the characters that can appear in the XML
id
attribute, but

usually you won’t use those special characters in a bean name. Moreover, Spring allows you to specify

multiple names, separated by commas, for a bean in the
name attribute. But you can’t do so in the
id

attribute because commas are not allowed there.

In fact, neither the bean name nor the bean ID is required for a bean. A bean that has no name

defined is called an anonymous bean. You will usually create beans like this that serve only to interact

with the Spring container itself; that you are sure you will only inject by type later on; or that you will

nest, inline, in the declaration of an outer bean.

Defining
Bean Properties by Shortcut

Spring
supports a shortcut for specifying the value of a simple type property. You can present a
value

attribute in the
<property> element instead of enclosing a
<value>
element inside.

<bean id="sequenceGenerator"
class="com.apress.springenterpriserecipes.sequence.SequenceGenerator">
<property name="prefix" value="30" />
<property name="suffix" value="A" />
<property name="initial" value="100000" />
</bean>
This shortcut also works for constructor arguments.
<bean name="sequenceGenerator"
class="com.apress.springenterpriserecipes.sequence.SequenceGenerator">
<constructor-arg value="30" />
<constructor-arg value="A" />
<constructor-arg value="100000" />
</bean>

Spring 2.0 provides another convenient shortcut for you to define properties. It’s by using the
p

schema to define bean properties as attributes of the
<bean>
element. This can shorten the lines of XML

configuration.

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<span style="font-family: TheSansMonoCondensed-Plain; font-size: 9pt;"><bean id="sequenceGenerator"
<span style="font-size: 9pt;">class="com.apress.springenterpriserecipes.sequence.SequenceGenerator"
<span style="font-family: TheSansMonoCondensed-Black; font-size: 9pt;">p:prefix="30" p:suffix="A" p:initial="100000" />
<span style="font-family: TheSansMonoCondensed-Plain; font-size: 9pt;"></beans></span></span></span><br style="orphans: 2; text-align: -webkit-auto; widows: 2;" /></span>

Configuring Collections for Your Beans

List,
Set, and
Map
are the core interfaces representing three main types of collections. For each

collection type, Java provides several implementations with different functions and characteristics from

which you can choose. In Spring, these types of collections can be easily configured with a group of

built-in XML tags, such as <list>,
<set>, and
<map>.

Suppose you are going to allow more than one suffix for your sequence generator. The suffixes will

be appended to the sequence numbers with hyphens as the separators. You may consider accepting

suffixes of arbitrary data types and converting them into strings when appending to the sequence

numbers.

Lists, Arrays, and Sets

First, let’s use a java.util.List
collection to contain your suffixes. A
list is an ordered and indexed

collection whose elements can be accessed either by index or with a for-each loop.

package com.apress.springenterpriserecipes.sequence;
...
public class SequenceGenerator {
...
private List<Object> suffixes;
public void setSuffixes(List<Object> suffixes) {
this.suffixes = suffixes;
}
public void setPrefixGenerator(PrefixGenerator prefixGenerator) {
this.prefixGenerator = prefixGenerator;
}
public synchronized String getSequence() {
StringBuffer buffer = new StringBuffer();
...
for (Object suffix : suffixes) {
buffer.append("-");
buffer.append(suffix);
}
return buffer.toString();
}
}

To define a property of the interface
java.util.List
in the bean configuration, you specify a
<list>

tag that contains the elements. The elements allowed inside the
<list>
tag can be a simple constant

value specified by <value>, a bean reference by
<ref>, an inner bean definition by
<bean>, or a null

element by <null>. You can even embed other collections in a collection.

<bean id="sequenceGenerator"
class="com.apress.springenterpriserecipes.sequence.SequenceGenerator">
<property name="prefixGenerator" ref="datePrefixGenerator" />
<property name="initial" value="100000" />
<property name="suffixes">
<list>
<value>A</value>
<bean class="java.net.URL">
<constructor-arg value="http" />
<constructor-arg value="www.apress.com" />
<constructor-arg value="/" />
</bean>
<null />
</list>
</property>
</bean>

Conceptually, an
array is very similar to a list in that it’s also an ordered and indexed collection that

can be accessed by index. The main difference is that the length of an array is fixed and cannot be

extended dynamically. In the Java Collections framework, an array and a list can be converted to each

other through the Arrays.asList()
and
List.toArray() methods. For your sequence generator, you can

use an Object[]
array to contain the suffixes and access them either by index or with a for-each loop.

package com.apress.springenterpriserecipes.sequence;
...
public class SequenceGenerator {
...
private Object[] suffixes;
public void setSuffixes(Object[] suffixes) {
this.suffixes = suffixes;
}
...
}

The definition of an array in the bean configuration file is identical to a list denoted by the

<list>
tag.

Another common collection type is a set. Both the
java.util.List
interface and the java.util.Set

interface extend the same interface:
java.util.Collection. A set differs from a list in that it is neither

ordered nor indexed, and it can store unique objects only. That means no duplicate element can be

contained in a set. When the same element is added to a set for the second time, it will replace the old

one. The equality of elements is determined by the
equals() method.

package com.apress.springenterpriserecipes.sequence;

   package com.apress.springenterpriserecipes.sequence;
...
public class SequenceGenerator {
...
private Set<Object> suffixes;
public void setSuffixes(Set<Object> suffixes) {
this.suffixes = suffixes;
}
...
}

To define a property of
java.util.Set
type, use the
<set>
tag to define the elements in the same way

as a list.

<bean id="sequenceGenerator"
class="com.apress.springenterpriserecipes.sequence.SequenceGenerator">
...
<property name="suffixes">
<set>
<value>A</value>
<bean class="java.net.URL">
<constructor-arg value="http" />
<constructor-arg value="www.apress.com" />
<constructor-arg value="/" />
</bean>
<null />
</set>
</property>
</bean>

Although there’s not an order concept in the original set semantics, Spring preserves the order of

your elements by using java.util.LinkedHashSet, an implementation of the
java.util.Set
interface

that does preserve element order.

Maps
and Properties

A
map
is a table that stores its entries in key/value pairs. You can get a particular value from a map by its

key, and also iterate the map entries with a for-each loop. Both the keys and values of a map can be of

arbitrary type. Equality between keys is also determined by the
equals() method. For example, you can

modify your sequence generator to accept a
java.util.Map collection that contains suffixes with keys.

package com.apress.springenterpriserecipes.sequence;
...
public class SequenceGenerator {
...
private Map<Object, Object> suffixes;
public void setSuffixes(Map<Object, Object> suffixes) {
this.suffixes = suffixes;
}
public synchronized String getSequence() {
StringBuffer buffer = new StringBuffer();
...
for (Map.Entry entry : suffixes.entrySet()) {
buffer.append("-");
buffer.append(entry.getKey());
buffer.append("@");
buffer.append(entry.getValue());
}
return buffer.toString();
}
}

In Spring, a map is defined by the
<map>
tag, with multiple
<entry>
tags as children. Each entry

contains a key and a value. The key must be defined inside the <key>
tag. There is no restriction on the

type of the key and value, so you are free to specify a <value>,
<ref>,
<bean>,
<idref>, or
<null>
element

for them. Spring will also preserve the order of the map entries by using
java.util.LinkedHashMap.

<bean id="sequenceGenerator"
class="com.apress.springenterpriserecipes.sequence.SequenceGenerator">
...
<property name="suffixes">
<map>
<entry>
<key>
<value>type</value>
</key>
<value>A</value>
</entry>
<entry>
<key>
<value>url</value>
</key>
<bean class="java.net.URL">
<constructor-arg value="http" />
<constructor-arg value="www.apress.com" />
<constructor-arg value="/" />
</bean>
</entry>
</map>
</property>
</bean>

There are shortcuts to defining map keys and values as attributes of the
<entry>
tag. If they are

simple constant values, you can define them by key
and
value. If they are bean references, you can

define them by key-ref
and
value-ref.

<pre name="code" class="html"><bean id="sequenceGenerator"
class="com.apress.springenterpriserecipes.sequence.SequenceGenerator">
...
<property name="suffixes">
<map>
<entry key="type" value="A" />
<entry key="url">
<bean class="java.net.URL">
<constructor-arg value="http" />
<constructor-arg value="www.apress.com" />
<constructor-arg value="/" />
</bean>
</entry>
</map>
</property>
</bean>

In all the collection classes seen thus far, you used values to set the properties. Sometimes the

desired goal is to configure a
null value using a
Map instance. Spring’s XML configuration schema

includes explicit support for this. Here is a map with null values for the value of an entry:

<property name="nulledMapValue">
<map>
<entry>
<key> <value>null</value> </key>
</entry>
</map>
</property>

A
java.util.Properties collection is very similar to a map. It also implements the
java.util.Map

interface and stores entries in key/value pairs. The only difference is that the keys and values of a

Properties
collection are always strings.

package com.apress.springenterpriserecipes.sequence;
...
public class SequenceGenerator {
...
private Properties suffixes;
public void setSuffixes(Properties suffixes) {
this.suffixes = suffixes;
}
...
}

To define a
java.util.Properties collection in Spring, use the
<props>
tag with multiple <prop>
tags

as children. Each <prop>
tag must have a key
attribute defined and the corresponding value enclosed.

<bean id="sequenceGenerator"
class="com.apress.springenterpriserecipes.sequence.SequenceGenerator">
...
<property name="suffixes">
<props>
<prop key="type">A</prop>
<prop key="url">http://www.apress.com/</prop>
<prop key="null">null</prop>
</props>
</property>
</bean>

If you define your beans with inheritance, a child bean’s collection can be merged with that of its

parent by setting the merge
attribute to
true. For a
<list>
collection, the child elements will be added.

来源:

Spring Enterprise Recipes: A Problem-Solution Approach  2016年2月10

Copyright ? 2009 by Gary Mak and Josh Long

All rights reserved. No part of this work may be reproduced or transmitted in any form or by any

means, electronic or mechanical, including photocopying, recording, or by any information

storage or retrieval system, without the prior written permission of the copyright owner and the

publisher.

ISBN-13 (pbk): 978-1-4302-2497-6

ISBN-13 (electronic): 978-1-4302-2498-3

Printed and bound in the United States of America 9 8 7 6 5 4 3 2 1

时间: 2024-11-06 19:13:19

Configuring Beans in the Spring IoC Container的相关文章

Spring IoC Container and Spring Bean Example Tutorial

Spring Framework is built on the Inversion of Control (IOC) principle. Dependency injection is the technique to implement IoC in applications. This article is aimed to explain core concepts of Spring IoC container and Spring Bean with example program

学习spring ioc的几点建议

写在前面的话Spring 是一个轻量级的企业级应用开发框架,经年累月的迭代spring已经包含了很多模块.其中包括springBoot,springframework,springdata,springcloud,博主想写一点关于spring全家桶的东西包括spring全家桶技术应用,如何看spring官网学习,如何看spring的源码.但是写博客是个技术活,而且东西比较多,希望我可以坚持下来每天写一点.本文是基于spring5的知识分析,比如后面的源码.比如官网.如果你看到的源码和官网和博文有

spring ioc 容器概念

spring ioc 容器 一个java应用程序是有很多类组成的,这些类相互协作.相互作用来提供应用程序的表现行为.那些被其它类组合提供某些行为的类,称之为其它类的依赖(dependencies).利用软件工程中的组合模式(经常是继承模式的反模式)来说,我们经常利用某些类组合成其它类,不管这些类是通过构造函数还是setter方法或其它方法,那么组合成其它类的那些类就是这个组合类的依赖.当组合类要表现出的行为依赖这些类的时候,这些类必须被创建并注入给组合类. 在spring应用中,spring i

介绍 Spring IoC 容器和 bean

简介 本章涵盖了 Spring Framework实现控制翻转 (IoC) 的原则. IoC 有时也被称为依赖注入 (DI).这是一个对象定义他们依赖的过程,其中对象之间的相关性,也就是说,它们一起工作,只能通过构造函数参数,参数工厂方法或设置在其构造后的对象实例或者是从一个工厂方法返回的对象实例的属性上.容器在创建的 bean 注入这些依赖.这个过程是根本的反转,因此称为控制反转(IoC),bean 本身通过直接构造类,或作为 Service Locator(服务定位器)模式的机制,来控制其依

Spring Core Container 源码分析三:Spring Beans 初始化流程分析

前言 本文是笔者所著的 Spring Core Container 源码分析系列之一: 本篇文章主要试图梳理出 Spring Beans 的初始化主流程和相关核心代码逻辑: 本文转载自本人的私人博客,伤神的博客: http://www.shangyang.me/2017/04/01/spring-core-container-sourcecode-analysis-beans-instantiating-process/ 本文为作者的原创作品,转载需注明出处: 源码分析环境搭建 参考 Sprin

Spring Ioc知识整理

Ioc知识整理(一): IoC (Inversion of Control) 控制反转. 1.bean的别名 我们每个bean元素都有一个id属性,用于唯一标识实例化的一个类,其实name属性也可用来标识一个类,我们还可以通过</alias>元素来给一个bean起一个别名: <bean name="doSpring" class="com.xiaoluo.spring.DoSpring"> </bean> <alias na

Spring4- 01 - Spring框架简介及官方压缩包目录介绍- Spring IoC 的概念 - Spring hello world环境搭建

一. Spring 框架简介及官方压缩包目录介绍 主要发明者:Rod Johnson 轮子理论推崇者: 2.1 轮子理论:不用重复发明轮子. 2.2 IT 行业:直接使用写好的代码. Spring 框架宗旨:不重新发明技术,让原有技术使用起来更加方便. Spring 几大核心功能 4.1 IoC/DI控制反转/依赖注入 4.2 AOP面向切面编程 4.3 声明式事务. Spring 框架runtime 5.1 test: spring 提供测试功能 5.2 Core Container:核心容器

Spring IOC 应用进阶

Spring IOC 应用进阶 1.1.Bean对象属性值的注入 在Spring中对Bean属性赋值的过程我们称之为依赖注入.Spring应用中为Bean的属性注入值的方式有两种,set注入和构造注入,set注入式通过对象的set方法为对象属性赋值,构造注入为通过bean对象的构造方法为属性注入值. 1.1.1.直接量值的注入 Spring 直接量值的注入指的是通过Spring IOC为对象的8种封装类以及String类型的属性注入值. 例如 定义OpenDataSouce类 public cl

Spring IOC 概述

Spring IOC 概述 IOC(Inversion of Control) 控制反转,也叫 DI(D_ependency injection_) 依赖注入.是一种设计思想.不过我并不同意所谓反转的说法,因为没有谁规定什么方式就是“标准”的,如果我把IOC作为“标准”,IOC就是“标准”自身,何来反转?不过我行文也是沿用官方的说法,使用IOC描述这个技术 IOC其实是一种组装的思想,最简单理解 IOC 的方法,就是我们的组装电脑. 主板,硬盘,显卡,CPU厂商们先定义好一个个插口. 然后主板厂