spring之装配bean

前言

在spring中,对象无需自己负责查找或创建与其关联的其他对象。相反,容器负责把需要相互协作的对象引用赋予各个对象,例如一个消费系统需要信誉证件,但它不需要自己创建,它只负责自己两手空空,而容器就赋予它一个信用卡认证组件。
通常,我们将创建应用对象间相互协作关系的行为称为装配。这也是依赖注入的本质。

一:声明bean

首先我们假想一个选秀场景,该bean为一个表演接口
public interface Performe {
public void perform();
}
很显然我们需要一些参赛者,而这些参赛者就需要spring帮我们创建了

二:创建spring配置

Spring是一个基于容器的框架,但是如果我们不对他进行任何配置,那么它就相当于一个空框架,一般情况下有采用XML或者注解式声明,这里都采用xml形式。

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
</beans>

三:声明一个简单的bean

这次表演者可以使各种各样的人,首先是一个杂技师。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Juggler implements Performe {
private int bigbang=5;
public Juggler(){
}
public Juggler(int bigbang){
this.bigbang=bigbang;
}
@Override
public void perform() {
System.out.println("it is "+bigbang);
}
}

主要打印出杂技师扔了多少块Bigbang;

接下来在spring中配置bean,

1
2
3
<bean id="juggle" class="com.zwl.dao.Juggler">
</bean>

这是一个最简单的声明格式
接下来就是加载spring上下文,进行测试

1
2
3
Juggler hello=(Juggler) ApplicaionContextUtil.getApplicationContext().getBean("juggle");
hello.perform();

ApplicaionContextUtil.xml

1
2
3
4
5
6
7
8
9
10
private static ApplicationContext ac=null;
private ApplicaionContextUtil(){
}
static{
ac=new ClassPathXmlApplicationContext("applicationContext.xml");
}
public static ApplicationContext getApplicationContext(){
return ac;
}

测试结果:

it is 5

四:通过构造器注入

有时候我们需要通过构造方法进行注入

1
2
3
<bean id="juggle" class="com.zwl.dao.Juggler">
<constructor-arg value="66"></constructor-arg>
</bean>

因为Juggle有一个代参和无参构造函数,默认不配置constructor-arg则是默认构造函数,相反则是代参构造函数,

构造器注入对象引用
上面是注入的基本类型,如果是一个对象了?
在Juggler类中增加如下代码

1
2
3
4
5
6
7
8
9
10
private Helloworld helloworld;
public Juggler(Helloworld helloworld){
this.helloworld=helloworld;
}
public void perform() {
System.out.println("it is "+bigbang);
helloworld.sayhello();
}

其中helloworld为入门时的程序

接下来就是配置文件

1
2
3
4
5
6
7
8
9
<bean id="helloworld" class="com.zwl.spring.Helloworld">
<property name="name">
<value>hello world!</value>
</property>
</bean>
<bean id="juggle" class="com.zwl.dao.Juggler">
<constructor-arg ref="helloworld"></constructor-arg>
</bean>

其中ref为注入另一个bean的id
测试结果:

it is 5
it is hello world

五:bean的作用域

所有的spring bean默认都是单例,即它总是返回同一个bean实例,通过在bean中的scope属性进行设置,一般有如下属性
Singleton 在每一个spring容器中,一个bean定义只对应一个对象实例(默认)
Prototype 允许bean的定义可以被实例化任意次(每次调用都创建一个实例)
另外还有request,session,global-session,一般只用前两者
测试代码:

1
2
3
Helloworld hello=(Helloworld) ApplicaionContextUtil.getApplicationContext().getBean("helloworld");
Helloworld hello1=(Helloworld) ApplicaionContextUtil.getApplicationContext().getBean("helloworld");
System.out.println(hello==hello1);

当采用默认scope时,测试结果为true

当进行如下修改时

1
<bean id="helloworld" class="com.zwl.spring.Helloworld" scope="prototype">

测试结果为false

另外在我们初始化和销毁bean时,需要在bean中配置

1
<bean id="helloworld" class="com.zwl.spring.Helloworld" scope="prototype" init-method="sayhello" destroy-method="saybyb">

其中sayhello与saybyb都是该类中方法,当在调用该bean之前,调用init-method,而在该bean销毁前,即生命周期结束前实现destroy-method,

六:注入bean属性

通常,javabean的属性时私有的,同时拥有一组set与get方法取出该属性,spring可以借助set配置属性的值
注意,这里和利用构造器的注入差不多
如注入简单值

1
2
<property name="name" value="hello world">
</property>

引用其他bean

1
<property name="hello" ref="helloworld"></property>

其中name中的值是该bean中的属性,名字要一致,而ref是该配置文件中的其他bean

七:装配集合

前面我们都是介绍单个对象的装配,对于复合类型该如何装配了
不妨模拟一个案例
首相是一个Student类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.zwl.spring;
public class Student {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

然后是School类,主要有的属性为集合,首先是list

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class School {
private List<Student> stulist;
public List<Student> getStulist() {
return stulist;
}
public void setStulist(List<Student> stulist) {
this.stulist = stulist;
}
}

配置的bean

1
2
3
4
5
6
7
<bean id="stu" class="com.zwl.spring.Student">
<property name="name" value="hello"></property>
</bean>
<bean id="stu1" class="com.zwl.spring.Student">
<property name="name" value="world"></property>
</bean>

简要说明一下,这里注入同一个类的不同bean,用于装入集合
然后是配置school

1
2
3
4
5
6
7
8
<bean id="sch" class="com.zwl.spring.School">
<property name="stulist">
<list>
<ref bean="stu"/>
<ref bean="stu1"/>
</list>
</property>
</bean>

一般格式如下,属性下,配置和要引入的bean

测试代码

1
2
3
4
School hello=(School) ApplicaionContextUtil.getApplicationContext().getBean("sch");
String name1=hello.getStulist().get(0).getName();
String name=hello.getStulist().get(1).getName();
System.out.println(name1+name);

测试结果:

helloworld

Set集合装配
首先在school类中加入如下属性

1
2
private Set<Student> stuset;
省略set与get方法

配置文件,添加如下:

1
2
3
4
5
6
<property name="stuset">
<set>
<ref bean="stu"/>
<ref bean="stu1"/>
</set>
</property>

对应测试代码:

1
2
3
4
5
6
School hello=(School) ApplicaionContextUtil.getApplicationContext().getBean("sch");
Iterator<Student> it=hello.getStuset().iterator();
while(it.hasNext()){
Student stu=it.next();
System.out.println(stu.getName());
}

这里通过迭代器取出对象
测试结果:

hello
world

Map集合装配
首先在school中添加如下属性:

1
2
private Map<String, Student> stumap;
省略set与get方法。。

配置文件,添加如下

1
2
3
4
5
6
<property name="stumap">
<map>
<entry key="11" value-ref="stu"></entry>
<entry key="22" value-ref="stu1"></entry>
</map>
</property>

其中,key为map的索引值,而value-ref为引用的bean
测试代码:

1
2
3
4
School hello=(School) ApplicaionContextUtil.getApplicationContext().getBean("sch");
String name=hello.getStumap().get("11").getName();
String name1=hello.getStumap().get("22").getName();
System.out.println(name+name1);

测试结果:

helloworld

热评文章