`

Spring3-装配Bean

阅读更多

本章类容来源于Spring in Action3第二章。

 

内容:

  • 声明bean
  • 构造器注入和setter方法注入
  • 装配bean
  • 控制bean的创建和销毁
声明bean
 观众朋友们好,这里是上海电视台,欢迎收看中国达人秀节目。
首先我们抽象出表演者角色。示例代码如下:
public interface Performer {
	public void perform();
}
 所有参与中国达人秀的同学都要实现该接口。
接下来,让我们来创建一个XML配置文件(Spring3支持注解方式,以后会讲到),告诉Spirng容器需要加载哪些Bean以及如何装配
Spring Xml配置文件的根元素来源于Spring beans命名空间的<beans>元素,一个典型的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   
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"  >
	

</beans>
 
beans命名空间并不是唯一的Spring命名空间,Spring核心只带了10个命名空间配置,如aop,context,mvc,util,tx等。以后会带来其他命名空间的更多信息。
现在,在开始选秀之前,节目组会讲报名的选秀节目分类,以便评委对相同类型的节目做比较。好了,第一种类型定义为杂技师( juggler),示例代码如下
public class Juggler implements Performer {
	
	private int beanBags = 3;
	
	public Juggler() {
	}

	public Juggler(int beanBags) {
		this.beanBags = beanBags;
	}

	public void perform() {
		System.out.println("juggler " + beanBags + " bags");
	}

}
 
那么,有请我们的第一位杂技师表演者duke来到舞台,在Spring xml配置文件中声明duke的Bean
<bean id="duke" class="in.action3.chapter2.Juggler"></bean>
 好了,我们使用下面的代码,给duke一个排练的机会
public static void main(String[] args) {
		ApplicationContext ctx = new ClassPathXmlApplicationContext("spring/inject-service.xml");
		Performer performer = (Performer)ctx.getBean("duke");
		performer.perform();
	}
 输出juggler 3 bags。
抛3个袋子不难,想要获得认可, 必须同时抛更多的袋子,让我们配置duke具有冠军潜质的杂技师。
构造器注入
 为了让评委心动,我们配置让duke同时抛15个袋子。
 <bean id="duke" class="in.action3.chapter2.Juggler">
        <constructor-arg value="15"></constructor-arg>
 </bean>
 如果不配置<constructor-arg/>,Spring使用默认的构造方法,配置了<constructor-arg/>,Spring将调用Juggler的另一个构造方法。
通过构造器注入引用
因为duke不仅是一位杂技师,还是一个会朗诵诗歌的杂技师。我们要定义一个新的类型PoeticJuggler,才能展现duke的才华。
public class PoeticJuggler extends Juggler {
	
	private Poem poem ;
	
	public PoeticJuggler(Poem poem) {
		super();
		this.poem = poem;
	}
	
	public PoeticJuggler(int bags, Poem poem) {
		super(bags);
		this.poem = poem;
	}
	

	@Override
	public void perform() {
		super.perform();
		System.out.println("while reciting ....");
		poem.recite();
	}
	
}
 PoeticJuggler持有Poem接口的引用,Poem接口定义:
public interface Poem {
	public void recite();
}
  我们定义一首诗Sonnet29,实现Poem接口:
public class Sonnet29 implements Poem {

	public void recite() {
		System.out.println("every body, now, I will recite Sonnet29, when ......");
	}

}
 在XML配置中,将Sonnet29声明为一个bean:
<bean id="sonnet29" class="in.action3.chapter2.Sonnet29"></bean>
 现在我们来声明一个PoeticJuggler的bean,讲sonnet29注入给它:
<bean id="poeticDuke" class="in.action3.chapter2.PoeticJuggler">
        <constructor-arg value="15"></constructor-arg>
        <constructor-arg ref="sonnet29"></constructor-arg>
 </bean>
 poeticDuke排练下:
public static void main(String[] args) {
		ApplicationContext ctx = new ClassPathXmlApplicationContext("spring/inject-service.xml");
		Performer performer = (Performer)ctx.getBean("poeticDuke");
		performer.perform();
	}
 
 通过工厂方法创建bean
    有时候静态工厂方法是实例化对象的唯一方法, Spring通过factory-method属性来实例化bean
现在我们来实现一个单例的舞台Stage:
public class Stage {
	private Stage(){};
	
	private static class StageSingletonHolder{
		static Stage instance = new Stage();
	}
	
	public static Stage getInstance(){
		return StageSingletonHolder.instance;
	}
}
 题外话:
并发环境下延迟加载单例实例的解决方案Initialization on Demand Holder
即把instance的初始化投入到一个内部类的初始过程中,就可以兼顾正确性和性能。 
  1. 内部类的初始化是延迟的,外部类初始化时不会初始化内部类。 
  2. 内部类的初始化是线程安全的,所以不用担心两个instance或半残instance的问题。 
  3. 第一次获取instance需要等它初始化,以后再获取就不必了,而且也不需要锁。所以在性能上也是妥妥的。
配置Stage Bean:
<bean id="stage" class="in.action3.chapter2.Stage" factory-method="getInstance"></bean>
 
Bean的作用域
 所有Spring Bean默认都是单例。如果每次请求时都要获得唯一的Bean实例,如何覆盖Spring默认的单例配置呢?
为此,我们为每个观众给予不同的门票,配置:
<bean id="ticket" class="in.action3.chapter2.Ticket" scope="prototype"></bean>
 通过scope属性来指定bean的作用域。
除了singleton, prototype之外,还有request,session, global-session作用域,这几个作用域用于web和portlet的上下文spring容器。
初始化和销毁Bean
为了定义Bean的初始化和销毁操作,只需要使用init-method和destory-method参数配置bean元素。
我们在舞台类加上turnOnLights()和turnOffLights()两个方法,表示舞台初始化是打开灯,舞台销毁是关闭灯。配置xml如下:
  <bean id="stage" class="in.action3.chapter2.Stage" factory-method="getInstance" 
            init-method="turnOnLights" destroy-method="turnOffLights"></bean>
如果上下文中有很多Bean拥有相同名字的初始化和销毁方法,可以使用  beans元素的default-init-method和default-destory-method属性。
<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"  
	default-init-method="turnOnLights"
	default-destroy-method="turnOffLights"
	>
为bean定义初始化和销毁操作的另一种方法是,bean实现Spring的InitializingBean和DisposableBean接口。分别实现其afterPropertiesSet()和destroy()两个方法。
 注入Bean属性

通常javaBean的属性是私有的,同时拥有一组存取器方法,以setXXX()和getXXX()形式存在,Spring可以借助属性的set方法来配置属性的值, 实现setter方式的注入。
为了演示setter注入,我们欢迎下一位表演者,表演乐器演奏。
public class Instrumentalist implements Performer {

	private Instrument instrument;
	
	private String 	song;
	
	public Instrument getInstrument() {
		return instrument;
	}
	public void setInstrument(Instrument instrument) {
		this.instrument = instrument;
	}
	public String getSong() {
		return song;
	}
	public void setSong(String song) {
		this.song = song;
	}
	public void perform() {
		System.out.println("表演的歌曲名字是:"+song);
		instrument.play();
	}

}
 定义乐器接口:
public interface Instrument {
	public void play();
}
 定义萨克斯乐器:
public class Saxophone implements Instrument {

	public void play() {
		System.out.println("TOOT TOOT TOOT");
	}

}
Spring 配置:
  <bean id="saxophone" class="in.action3.chapter2.Saxophone"></bean>
    <bean id="kenney" class="in.action3.chapter2.Instrumentalist">
        <!-- setter注入简单的值 -->
        <property name="song" value="Jinle bells"></property>
        <!-- setter注入bean -->
        <property name="instrument" ref="saxophone"></property>
    </bean>
 执行代码:
public static void main(String[] args) {
		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring/inject-service.xml");
		Performer performer = (Performer)ctx.getBean("kenney");
		performer.perform();
		ctx.close();
	}
 输出:
表演的歌曲名字是:Jinle bells
TOOT TOOT TOOT
 注入内部Bean
   <bean id="kenney" class="in.action3.chapter2.Instrumentalist">
        <!-- setter注入简单的值 -->
        <property name="song" value="Jinle bells"></property>
        <!-- setter注入bean -->
        <property name="instrument" >
            <!-- 注入内部Bean,该bean是kenney私有的 -->
            <bean class="in.action3.chapter2.Saxophone"></bean>
        </property>
    </bean>
内部bean不能复用,且会影响配置文件的可读性。
使用Spring的命名空间p装配属性
使用命名空间p,需要在spring xml配置中添加声明,如下:
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p"
	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"  
	>
 重新定义kenney bean配置
    <bean id="saxophone" class="in.action3.chapter2.Saxophone"></bean>
    <bean id="kenney" class="in.action3.chapter2.Instrumentalist" p:song="Jinle bells"
        p:instrument-ref="saxophone">
    </bean>
 使用<porperty>还是p取决于你, 他们是等价的,p的主要优点是简洁。
装配集合List Set
装配集合类型的属性时,Spring提供了4种类型的集合装配元素。<list>,<set>,<map>,<props>
我们有请下一位达人,他也是乐器表演, 但他可以同时演奏多个乐器。
一个人乐队OneManBand 
public class OneManBand implements Performer {
	private Collection<Instrument> instruments;
	public Collection<Instrument> getInstruments() {
		return instruments;
	}
	public void setInstruments(Collection<Instrument> instruments) {
		this.instruments = instruments;
	}
	public void perform() {
		for (Instrument instrument : instruments) {
			instrument.play();
		}
	}
}
配置hank为一个人乐队
   <bean id="hank" class="in.action3.chapter2.OneManBand">
        <property name="instruments">
            <list>
               <ref bean="saxophone"/>
               <ref bean="guitar"/>
               <ref bean="harmonica"/>
            </list>
        </property>
    </bean>
装配Map属性
hank在演奏的时候,希望打印出乐器的名字,我们修改下OneManBand
public class OneManBand implements Performer {
	private Map<String, Instrument> instruments;
	public Map<String, Instrument> getInstruments() {
		return instruments;
	}
	public void setInstruments(Map<String, Instrument> instruments) {
		this.instruments = instruments;
	}
	public void perform() {
		for (Entry<String, Instrument> entry : instruments.entrySet()) {
			System.out.println("乐器:"+entry.getKey()+" 演奏:");
			entry.getValue().play();
		}
	}
}
 配置:
    <bean id="hank" class="in.action3.chapter2.OneManBand">
        <property name="instruments">
             <map>
                <entry key="saxophone" value-ref="saxophone"></entry>
                <entry key="guitar" value-ref="guitar"></entry>
                <entry key="harmonica" value-ref="harmonica"></entry>
             </map>
        </property>
    </bean>
 
装配propertis集合
如果map的键值都为String,可以使用java.util.Properties代替map。
为了演示,我们修改下OneManBand
public class OneManBand implements Performer {
	private Properties instruments;
	public Properties getInstruments() {
		return instruments;
	}
	public void setInstruments(Properties instruments) {
		this.instruments = instruments;
	}
	public void perform() {
		for (Entry<Object, Object> entry : instruments.entrySet()) {
			System.out.println("乐器:"+entry.getKey()+" 演奏:"+ entry.getValue());
		}
	}
}
 配置:
	<bean id="hank" class="in.action3.chapter2.OneManBand">
		<property name="instruments">
			<props>
				<prop key="saxophone">saxophone</prop>
				<prop key="guitar">guitar</prop>
				<prop key="harmonica">harmonica</prop>
			</props>
		</property>
	</bean>
 
装配空值
显式的为属性装配null值,使用<null/>
例如:
<property name="someNullProperty"><null/></property>
 
分享到:
评论

相关推荐

    基于框架的Web开发-装配Bean自动装配.doc

    Spring通过组件扫描(Component Scanning)和自动装配(Autowiring)来实现这一目标,使得开发者无需手动配置大部分bean的依赖关系。 首先,我们来看组件扫描。组件扫描允许Spring容器自动发现应用上下文中创建的...

    Spring框架(spring-framework-5.2.6.RELEASE)的jar包

    Beans模块则实现了bean的定义、实例化、装配和管理。 2. **Data Access/Integration**:这个模块支持数据访问,包括JDBC、ORM(Object-Relational Mapping)、OXM(Object-XML Mapping)和JMS(Java Message ...

    Spring--2.Spring 中的 Bean 配置-4

    `Spring--2.Spring 中的 Bean 配置-4-3.zip`文件中可能包含这样的例子: ```java @Configuration public class AppConfig { @Bean public ExampleBean exampleBean() { return new ExampleBean(); } @Bean ...

    spring注解开发--Bean加载控制.zip

    自动装配是Spring的一个重要特性,`@Autowired`注解用于自动将依赖注入到bean中。Spring会根据类型或名称来匹配依赖并注入。 6. **@Qualifier** 当有多个相同类型的bean时,`@Qualifier`可以用来指定注入哪个特定...

    spring-aop-3.0.xsd spring-beans-3.0 spring-context-3.0.xsd spring-mvc-3.1.xsd

    `spring-beans-3.0.xsd` 文件定义了 Spring 容器如何读取并解析 XML 配置文件,来实例化、装配和管理 beans。在这个文件中,你可以定义 bean 的 id、class、属性、依赖注入等。通过版本号 3.0,我们可以看出这是针对...

    Spring--2.Spring 中的 Bean 配置-2-1

    在Spring框架中,Bean配置是核心概念之一,它关乎到对象的创建、初始化、装配以及管理。本节我们将深入探讨Spring中的Bean配置,主要聚焦在XML配置方式,因为这是Spring早期版本中最常用的方式,尽管在现代Spring...

    Spring4--2.bean注解和AOP

    3. `@Autowired`:这个注解用于自动装配Bean的依赖。Spring会根据类型或名称找到合适的Bean进行注入。例如: ```java @Service public class MyService { @Autowired private MyDependency myDependency; // ... ...

    跟我学spring3-源码.

    5. **Bean的生命周期管理**:Spring容器管理的对象称为Bean,它负责Bean的初始化、属性设置、后处理器调用以及销毁等各个生命周期阶段。 6. **事务管理**:Spring提供了声明式和编程式的事务管理,使得开发者可以...

    spring bean XML配置入门

    在本文中,我们将深入探讨Spring框架中的Bean XML配置,这是Spring的核心特性之一,它允许我们定义、管理和装配应用中的对象。我们将围绕以下知识点展开: 1. **Spring框架基础**: Spring是一个开源的Java平台,...

    day38 16-Spring的Bean的装配:注解的方式

    以上就是Spring使用注解方式装配Bean的基本过程和关键注解的介绍。通过这种方式,我们可以轻松地管理Bean的生命周期,实现依赖注入,以及对Bean的其他配置,极大地提高了代码的可维护性和灵活性。在实际项目中,结合...

    spring-framework-5.0.4.RELEASEspring-framework-5.0.4.RELEASE

    Spring是什么呢?首先它是一个开源的项目,而且目前非常活跃...它实现了很优雅的MVC,对不同的数据访问技术提供了统一的接口,采用IOC使得可以很容易的实现bean的装配,提供了简洁的AOP并据此实现Transaction Management

    Spring--2.Spring 中的 Bean 配置-3

    在Spring框架中,Bean配置是核心概念之一,它关乎到对象的创建、初始化、装配以及管理。本节我们将深入探讨Spring中的Bean配置,主要聚焦在第三部分,这通常涉及到更高级和灵活的配置方式。 首先,Spring允许我们...

    spring入门学习-3、Bean装配(XML).pdf

    6. **Autowiring-mode**:定义了如何自动装配Bean。Spring支持按类型、按名称等多种自动装配模式。 7. **Lazy-initialization-mode**:懒加载模式,表示Bean是否在容器启动时立即创建,还是在首次请求时创建。 8. ...

    spring装配bean实例代码

    本文将深入探讨Spring装配Bean的实例代码,帮助你更好地理解这一关键概念。 首先,Spring装配Bean主要有两种方式:XML配置和注解配置。在本例中,我们将重点关注XML配置,对应的压缩包文件名为“springxmldemo”,...

    撸一撸Spring Framework-IoC-BeanDefinition(csdn)————程序.pdf

    如`scope`(作用域)、`abstract`(是否为抽象bean)、`lazy-init`(是否延迟初始化)、`autowire`(自动装配模式)、`depends-on`(依赖的其他bean)、`init-method`(初始化方法)和`destroy-method`(销毁方法)...

    spring3--最小系统

    9. **依赖注入**:Spring的核心特性之一,通过@Autowired注解自动装配bean的依赖。 10. **RESTful Web服务**:如何使用Spring MVC创建符合REST原则的服务,如HTTP动词(GET、POST、PUT、DELETE)的映射。 在压缩包...

    官方spring-framework-4.3.13.RELEASE完整包

    Spring框架允许开发者通过XML配置来装配bean,这些XML配置文件遵循特定的schema。此压缩包提供了所有schema文件,比如`beans.xsd`、`context.xsd`等,它们定义了如何使用XML进行bean的声明、属性的设置以及依赖关系...

    spring-framework-5.1.8.RELEASE.zip

    3. **Web模块**:如`spring-web`, `spring-webmvc`,提供了构建Web应用程序的支持,`spring-webmvc`是Spring MVC,一个强大的MVC框架,用于处理HTTP请求和响应。 4. **AOP模块**:`spring-aop`和`spring-aspects`...

    spring-framework-4.2.0.RELEASE官方完整包加官方文档

    此外,Spring的容器是整个框架的核心,它管理所有bean的生命周期。在4.2.0版本中,容器的启动速度得到了提升,同时增强了对 Profiles 的支持,使得环境特定的配置变得更加容易。 文档方面,`spring-framework-4.2.0...

Global site tag (gtag.js) - Google Analytics