前言
Bean(汉译咖啡豆). 又称JAVA Bean.其实就是JAVA程序中的一个个对象,所以Bean的管理其实就是spring对于JAVA程序中的对象的管理。Spring中提供了两种方式来管理Bean:
- 基于XML方式的Bean管理
- 基于注解方式的Bean管理
本节主要讲述XML方式管理Bean。
基于XML方式的Bean管理
1. bean的属性标签
<bean id="user1" class="com.mayuanfei.springioc.User" name="user11" lazy-init="true" scope="prototype"/>
| 属性名 | 含义 |
|---|---|
| id | 对象的id |
| class | 类的全路径名 |
| name | 和id功能类似,也是用于获得该bean |
| lazy-init | 懒加载,默认false。 true:调用getBean的时候再去实例化对象 |
| scope | 控制对象单例多例和使用范围 1. singleton(默认值):Spring容器中只会存在一个共享的bean实例 2. prototype:每一次获取都会产生一个新的bean实例,相当与一个new的操作 3. request:表示针对每一次HTTP请求都会产生一个新的bean, 同时该bean仅在当前HTTP request内有效 4. session:作用域表示针对每一次HTTP请求都会产生一个新的bean, 同时该bean仅在当前HTTP session内有效 5. global session:类似于标准的HTTP Session作用域,不过它仅仅在 基于portlet的web应用中才有意义 |
注意:
上面的
<bean id="user"...表示调用User类的默认构造方法。如果该方法中没有默认构造方法,则报错。
2. 通过Set方法给对象赋值
<bean id="user2" class="com.mayuanfei.springioc.User" lazy-init="true">
<property name="userId" value="1"/>
<property name="userName" value="老马"/>
<property name="address" value="北京朝阳"/>
</bean>
3. 通过构造方法给对象赋值
<!--
constructor-arg 使用构造方法实现依赖注入
constructor-arg 的个数必须和某个构造方法的参数个数相对应
-name:指的是参数名
-index:指的是参数的索引
-value:指的是参数值
-->
<bean id="user3" class="com.mayuanfei.springioc.User" lazy-init="true">
<constructor-arg name="userId" value="3"/>
<constructor-arg name="userName" value="老马3"/>
<constructor-arg name="address" value="北京顺义3"/>
</bean>
<bean id="user33" class="com.mayuanfei.springioc.User" lazy-init="true">
<constructor-arg index="0" value="33"/>
<constructor-arg index="1" value="老马33"/>
<constructor-arg index="2" value="北京顺义33"/>
</bean>
4. 通过p名称空间和c名称空间给对象赋值
-
添加约束
<?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:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">这里的xmlns:p和xmlns:c就是新加入的命名空间。
-
进行配置
<!-- p名称空间,就是对property的简化处理 c名称空间,就是对constructor-arg的简化 --> <bean id="user4" class="com.mayuanfei.springioc.User" lazy-init="true" p:userId="4" p:userName="老马4" p:address="北京朝阳4"/> <bean id="user44" class="com.mayuanfei.springioc.User" lazy-init="true" c:userId="44" c:userName="老马44" c:address="北京朝阳44"/>
5. 注入特殊字符
<!--
null值注入和特殊字符注入
& : &
< : <
> : >
-->
<bean id="user5" class="com.mayuanfei.springioc.User" lazy-init="true">
<property name="userId">
<null/>
</property>
<property name="userName" value="老马5&<>"/>
<property name="address">
<value><![CDATA[北京顺义5&<>]]></value>
</property>
</bean>
6. Bean引用
<bean id="book6" class="com.mayuanfei.springioc.Book" lazy-init="true">
<property name="bookName" value="04.spring-ioc-Bean管理"/>
<property name="author" ref="user5"/>
</bean>
7. 各种集合注入
-
添加约束
-
进行配置
<!-- 集合注入 --> <bean id="student7" class="com.mayuanfei.springioc.Student" lazy-init="true"> <!--数组属性注入--> <property name="books"> <array> <value>01.spring简介</value> <value>02.spring-ioc概念</value> <value>03.spring-ioc实现原理</value> </array> </property> <!--set集合注入--> <property name="bookSet"> <set> <value>01.spring简介</value> <value>02.spring-ioc概念</value> <value>03.spring-ioc实现原理</value> </set> </property> <!--list集合注入--> <property name="bookList"> <list> <value>01.spring简介</value> <value>02.spring-ioc概念</value> <value>03.spring-ioc实现原理</value> </list> </property> <!--map集合注入--> <property name="bookMap"> <map> <entry key="01.spring简介" value="老马"/> <entry key="02.spring-ioc概念" value="老马"/> <entry key="03.spring-ioc实现原理" value="老马"/> </map> </property> <!--List对象集合注入--> <property name="bookList2" ref="publicbookList"/> </bean> <!--定义公共集合--> <util:list id="publicbookList"> <!--声明多个Book对象--> <bean id="b1" class="com.mayuanfei.springioc.Book" p:bookName="01.spring简介" p:author-ref="user5"/> <bean id="b2" class="com.mayuanfei.springioc.Book" p:bookName="02.spring-ioc概念" p:author-ref="user4"/> <bean id="b3" class="com.mayuanfei.springioc.Book" p:bookName="03.spring-ioc实现原理" p:author-ref="user3"/> </util:list>
8. 工厂方式创建对象
-
继承AbstractFactoryBean类
核心思路就是实现FactoryBean来创建具体的实例对象,可以实现FactoryBean的虚基类AbstractFactoryBean类实现。代码如下:
public class BookFacotry extends AbstractFactoryBean<Book> { @Override public Class<?> getObjectType() { return null; } @Override protected Book createInstance() throws Exception { Book book = new Book(); book.setBookName("01.spring简介"); book.setAuthor(new User("user8", "老马8", "北京顺义8")); return book; } }继承关系如下:
-
配置文件
<!-- 工厂方式创建对象 --> <bean id="book8" class="com.mayuanfei.springioc.BookFacotry"/>
9. 自动注入
-
配置文件
<bean id="author" class="com.mayuanfei.springioc.User" > <property name="userId" value="1"/> <property name="userName" value="老马"/> <property name="address" value="北京朝阳"/> </bean> <bean id="book" class="com.mayuanfei.springioc.Book" autowire="byName" > <property name="bookName" value="java设计模式"/> </bean>autowire可以使容器中管理的对象自动注入到当前对象中,它有byName和byType两种方式。
-
byName
byName 根据目标id值和属性值注入,要保证当前对象的属性值和目标对象的id值一致,比如这里User之所以id为author,是因为Book类中定义作者的变量名为:author
@Data public class Book { /** * 书籍名称 */ private String bookName; /** * 作者 */ private User author; } -
byType
根据类型注入,要保证相同类型的目标对象在容器中只有一个实例。此时可以不用在意id起的名字了。
-
10. 读取外部属性文件
spring容器可以读取.properties属性配置文件,可以将文件中的信息注入给bean
-
增加context名称空间
-
修改配置
<!-- 这里注意文件编码格式的设置,否则很容易出现乱码 --> <context:property-placeholder location="classpath:user.properties" file-encoding="utf-8"/> <!-- User对象的属性值通过属性文件中的值来设置 --> <bean id="user" class="com.mayuanfei.springioc.User" > <property name="userId" value="${user.userId}"/> <property name="userName" value="${user.userName}"/> <property name="address" value="${user.address}"/> </bean>
11. 代码地址
gitee.com/mayuanfei/S… 下的SpringIoc03
记忆印记
- spring容器默认会在容器启动时就会去创建对象,而如果不想这样可以用
lazy-init="true"来解决 - Spring容器内的对象默认都是单例的,如果希望每次new出新对象可以用
scope=prototype来解决 - 通过property来调用set方法设置属性值;通过constructor-arg来调用构造方法设置属性值
- 特殊字符记得用转义符
- bean的引用采用ref来指定
- 自动注入有byName和byType两种类型
- 可以通过属性文件来设置对象属性值