Spring管理Bean(xml)-IOC
Spring管理Bean(xml)-IOC
Spring中的一大核心概念是IOC(Inversion of Control,控制反转),简单来说IOC就是统一管理应用程序中的bean对象。IOC负责创建、配置和管理Bean对象的生命周期,以及处理bean之间的依赖关系。在传统web开发方式中,需要不断创建对象,完成相应的业务逻辑,而spring则简化了这一过程,spring通过IOC统一管理了bean对象,需要时只需要从ioc中直接取出即可。
xml方式配置Bean
基础配置bean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53public class Monster { //bean对象
private Integer id;
private String name;
private String skill;
public Monster() {
}
public Monster(Integer id, String name, String skill) {
this.id = id;
this.name = name;
this.skill = skill;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSkill() {
return skill;
}
public void setSkill(String skill) {
this.skill = skill;
}
//xml文件中配置bean
<bean class="com.mhl.spring.bean.Monster" id="monster01">
<property name="id" value="100"/>
<property name="name" value="牛魔王"/>
<property name="skill" value="芭蕉扇"/>
</bean>
//获取bean对象
public void getMonster(){
ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
Monster monster =ioc.getBean("monster01", Monster.class);
System.out.println(monster.getId());
}【注意】:
- 如果没有配置id,系统会默认分配id,分配id的规则是 全类名#0,全类名#1……
- 在获取bean对象时,可以通过id,类型或id+类型的方式,通过id获取时,返回的是Object对象,可以强转成Monster;用类型获取时,要求ioc容器中只能有一个同一个类的bean;用id+类型的方式则可以直接返回bean类型的对象。
通过构造器配置bean
1
2
3
4
5
6
7
8
9
10
11
12
13<!-->index为构造器参数的位置<-->
<bean class="com.mhl.spring.bean.Car" id="car03">
<constructor-arg value="001" index="0"/>
<constructor-arg value="奔驰" index="1"/>
<constructor-arg value="330000" index="2"/>
</bean>
<!-->type为构造器参数的类型<-->
<bean class="com.mhl.spring.bean.Car" id="car04">
<constructor-arg value="002" type="java.lang.Integer"/>
<constructor-arg value="小米SU7" type="java.lang.String"/>
<constructor-arg value="219800" type="java.lang.String"/>
</bean>通过p名称空间配置bean
1
2
3
4
5<bean class="com.mhl.spring.bean.Car" id="car02"
p:id="002"
p:name="宝马"
p:price="300000"
/>【注意】使用p名称空间时,需要在xml文件上配置xmlns:p=”http://www.springframework.org/schema/p“
bean对象之间的相互引用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<!-->先创建memberDAOImpl,再创建memberDAO<-->
<bean id="memberDAOImpl" class="com.hspedu.spring.dao.MemberDAOImpl"/>
<bean id="memberServiceImpl" class="com.hspedu.spring.service.MemberServiceImpl">
<property name="memberDAO" ref="memberDAOImpl"/>
</bean>
<!-->如果按照以下配置,会先创建 department01 对象,再创建 student01 对象.<-->
<bean id="student01" class="com.hspedu.bean.Student" depends-on="department01"/>
<bean id="department01" class="com.hspedu.bean.Department" />
<!-- 引用/注入内部 bean 对象, 直接在配置 bean 时注入-->
<bean id="memberServiceImpl02"
class="com.hspedu.spring.service.MemberServiceImpl">
<property name="memberDAO">
<bean class="com.hspedu.spring.dao.MemberDAOImpl"/>
</property>
</bean>【注意】如果存在对象间的相互引用,spring会先将所需对象都创建出来,然后再引用
bean对象的集合/数组类型赋值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60<!-- 给集合属性注入值-->
<bean id="master01" class="com.hspedu.spring.beans.Master">
<property name="name" value="太上老君"/>
<!-- 给 bean 对象的 list 集合赋值 -->
<property name="monsterList">
<list>
<ref bean="monster03"/>
<ref bean="monster02"/>
</list>
</property>
<!-- 给 bean 对象的 map 集合赋值 -->
<property name="monsterMap">
<map>
<entry>
<key>
<value>monsterKey01</value>
</key>
<ref bean="monster01"/>
</entry>
<entry>
<key>
<value>monsterKey02</value>
</key>
<ref bean="monster02"/>
</entry>
</map>
</property>
<!-- 给 bean 对象的 properties 集合赋值 -->
<property name="pros">
<props>
<prop key="k1">Java 工程师</prop>
<prop key="k2">前端工程师</prop>
<prop key="k3">大数据工程师</prop>
</props>
</property>
<!-- 给 bean 对象的数组属性注入值 -->
<property name="monsterName">
<array>
<value>银角大王</value>
<value>金角大王</value>
</array>
</property>
<!-- 给 bean 对象的 set 属性注入值 -->
<property name="monsterSet">
<set>
<!-- 引用方式-->
<ref bean="monster01"/>
<!--内部bean方式-->
<bean class="com.hspedu.spring.beans.Monster">
<property name="monsterId" value="10"/>
<property name="name" value="玉兔精"/>
<property name="skill" value="钻地洞"/>
</bean>
</set>
</property>
</bean>通过util名称空间创建list
1
2
3
4
5
6
7
8
9
10
11<util:list id="myListBook">
<value>三国演义</value>
<value>西游记</value>
<value>红楼梦</value>
<value>水浒传</value>
</util:list>
<bean id="bookStore" class="com.hspedu.spring.beans.BookStore">
<property name="bookList" ref="myListBook"/>
</bean>
<!-- bookList为list -->【注意】使用util名称空间时,需要在xml文件上配置xmlns:util=”http://www.springframework.org/schema/util“
级联属性赋值
(级联属性赋值即给对象的属性的属性赋值)
1
2
3
4
5
6
7<bean id="emp" class="com.hspedu.spring.beans.Emp">
<property name="name" value="jack"/>
<property name="dept" ref="dept"/>
<property name="dept.name" value="Java 开发部"/>
</bean>
<bean id="dept" class="com.hspedu.spring.beans.Dept"/>bean配置信息重用
1
2
3
4
5
6
7
8
9
10<!-- 继承的方式来实现 bean 配置信息的重用 -->
<bean id="monster10" class="com.hspedu.spring.beans.Monster">
<property name="monsterId" value="10"/>
<property name="name" value="蜈蚣精"/>
<property name="skill" value="蜇人"/>
</bean>
<!-- parent="monster10" 就是继承使用了 monster10 的配置信息 -->
<bean id="monster11" class="com.hspedu.spring.beans.Monster"
parent="monster10"/>1
2
3
4
5
6
7
8
9
10<!-- 当我们把某个bean设置为 abstract="true" 这个bean只能被继承, 而不能实例化了 -->
<bean id="monster12" class="com.hspedu.spring.beans.Monster" abstract="true">
<property name="monsterId" value="12"/>
<property name="name" value="美女蛇"/>
<property name="skill" value="吃人"/>
</bean>
<!-- parent="monster12" 就是继承使用了 monster12 的配置信息 -->
<bean id="monster13" class="com.hspedu.spring.beans.Monster"
parent="monster12"/>bean对象的单例和多例
【注意】:
- 在 spring 的 ioc 容器, 在默认情况下是安照单例创建的, 即配置一个 bean 对象后,ioc 容器只会创建一个 bean 实例。
- 如果,我们希望 ioc 容器配置的某个 bean 对象,是以多个实例形式创建的则可以通过配置 scope=”prototype” 来指定 。
- 默认是单例 singleton, 在启动容器时, 默认就会创建 , 并放入到 singletonObjects 集合 。
- 当
<bean scope="prototype" >设置为多实例机制后, 该 bean 是在 getBean()时才创
建 。 - 如 果 是 单 例 singleton, 同 时 希 望 在 getBean 时 才 创 建 , 可 以 指 定 懒 加 载
lazy-init=”true” (注意默认是 false,空间换时间)
1
<bean name="car" scope="prototype" class="com.hspedu.spring.beans.Car"/>
bean的生命周期
【注意】
- 执行构造器
- 执行 set 相关方法
- 调用 bean 的初始化的方法(需要配置)
- 使用 bean
- 当容器关闭时候, 调用 bean 的销毁方法(需要配置)
1
2
3
4
5<!-- 配置 bean 的初始化方法和销毁方法 -->
<bean id="house" class="com.hspedu.spring.beans.House" init-method="init"
destroy-method="destory">
<property name="name" value="北京豪宅"/>
</bean>配置bean的后置处理器
- bean的后置处理器 是在bean初始化方法前和初始化调用后被调用
- 可以对容器内所有对象进行统一处理,比如日志处理/权限的校验/安全的验证/事务的管理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39public class MyBeanPostProcessor implements BeanPostProcessor {
/**
* 什么时候被调用: 在Bean的init方法前被调用
* @param bean 传入的在IOC容器中创建/配置Bean
* @param beanName 传入的在IOC容器中创建/配置Bean的id
* @return Object 程序员对传入的bean 进行修改/处理【如果有需要的话】 ,返回
* @throws BeansException
*/
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization().. bean="
+ bean + " beanName=" + beanName);
//初步体验案例: 如果类型是House的统一改成 上海豪宅
//对多个对象进行处理/编程==>切面编程
if(bean instanceof House) {
((House)bean).setName("上海豪宅~");
}
return null;
}
/**
* 什么时候被调用: 在Bean的init方法后被调用
* @param bean 传入的在IOC容器中创建/配置Bean
* @param beanName 传入的在IOC容器中创建/配置Bean的id
* @return 程序员对传入的bean 进行修改/处理【如果有需要的话】 ,返回
* @throws BeansException
*/
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization().. bean="
+ bean + " beanName=" + beanName);
return bean;
}
}1
2
3
4
5
6
7
8
9<!-- 配置 bean 的初始化方法和销毁方法 -->
<bean id="house" class="com.hspedu.spring.beans.House" init-method="init"
destroy-method="destory">
<property name="name" value="北京豪宅"/>
</bean>
<!-- bean 后置处理器的配置 -->
<bean id="myBeanPostProcessor" class="com.hspedu.spring.beans.MyBeanPostProcessor" />
</beans>通过属性文件给bean注入值
1
2
3
4//.properties
name=\u9EC4\u888D\u602A
id=10
skill=\u72EE\u5B50\u543C1
2
3
4
5
6<context:property-placeholder location="classpath:my.properties"/>
<bean id="monster100" class="com.hspedu.spring.beans.Monster">
<property name="monsterId" value="${id}"/>
<property name="name" value="${name}"/>
<property name="skill" value="${skill}"/>
</bean>【注意】使用context名称空间时,需要在xml文件上配置xmlns:context=”http://www.springframework.org/schema/context“
配置bean的方式还有很多,就不再一一列举,后期主要是通过注解方式配置,xml作为了解即可。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 H-Loong!
评论
ValineDisqus


