Spring前面一阵已经有了很多次的使用,为了解决前一阵项目中的种种疑惑,开始“应用层面”的学习。
bean 基本
bean 存活在一个 ApplicationContext 中,不同的 ApplicationContext 将不同 beans 隔离开来,ApplicationContext 可以存在继承关系,通过继承关系实现不同 ApplicationContext 中的 beans 的通信。
基本注入方式很简单,包括:
- 属性注入
- 构造器注入
- 工厂方法注入
name 与 id
id 是 Ioc 容器中 bean 的唯一标识,命名规则需要满足 XML 的规定:以字母开头后面跟完整结束符(full stops)。name为 bean 的名字,没有字符限制。
// 可以指定多个 name 和 id,分隔符为逗号
<bean name="#tom,#carry"/>
匿名的 bean
即没有 id 的 bean。如何获得匿名 bean?通过#index
来获得对应的 bean
<bean class="com.bean.Bean" />
<bean class="com.bean.Bean" />
<bean class="com.bean.Bean" />
// 获得第 1 个 bean
getBean("com.bean.Bean");
// 获得第 2 个 bean
getBean("com.bean.Bean#1");
// 获得第 3 个 bean
getBean("com.bean.Bean#1");
构造器注入时的参数匹配问题
有两种方式进行匹配,如果没有指定匹配的方式,则默认选择类型匹配。
- 通过使用
index
属性,根据参数的顺序进行注入(index 从 0 开始) 通过使用
type
属性,根据参数的类型进行注入// 构造器 public Bean(String name, int num) { this.name = name; this.num = num; } // type 注入方式 <bean id="bean" class="com.bean.Bean"> <constructor-arg type="int" value="10"/> <constructor-arg type="java.lang.String" value="myBean" /> </bean> // index 注入方式 <bean id="bean" class="com.bean.Bean"> <constructor-arg index="0" value="mybean"/> <constructor-arg index="1" value="10" />
工厂类注入
工厂类分为:静态工厂方法注入和非静态工厂方法注入
// 非静态
<bean id="beanFactory" class="com.bean.BeanFactory" />
<bean id="non-static" class="com.bean.goods" factory-bean="beanFactory" factory-method="getInstance" />
// 静态(其中 class 必须为工厂类,getInstance() 为静态方法)
<bean id="non-static" class="com.bean.BeanFactory" factory-method="getInstance" />
注入遇到的小细节
参数中含有特殊字符
在 XML 文件中不能含有:""
、<>
、&
,当遇到这样的字符值时,有两种处理办法- 使用
![CDATA[]]
-
<value>![CDATA[公汽&出租车]]</value>
- 使用
null 值
可以在注入的时候赋值为null
<value><null/></value>
使用级联
// 调用 car.setName() 来对 car.name 进行赋值 <property name="car.name" value="BMW" />
使用
<set>
和<list>
对数组进行注入
set 与 list 标签有一点不同,set 注入的时候,元素不允许有重复
方法注入
当使用方法获取对象进行注入的时候,可以使用下面方式
lookup方法注入
通过这种方式,实现每次获得的 bean 均为一个新实例化的 bean<!-- 方法注入例子 --> <bean id="bmw-car" class="inectfunc.Car" scope="prototype"> <property name="brand" value="BMW"/> <property name="price" value="100"/> </bean> <bean id="magic-boss" class="inectfunc.MagicBoss"> <lookup-method name="getCar" bean="bmw-car"/> </bean>
replace方法替换
很少用到,用于将一个创建对象的方法进行替换
bean 的作用域
bean 的作用域一共有四个,这里只介绍两个
- singleton:在 Spring Ioc 容器中,仅有一个 Bean 实例
- prototype:每次从容器调用 Bean 时,都返回一个新的实例
bean 的注解
@Repository、@Service、@Controller、@Component为类注解,注解的类都会转化为被 Spring 管理的 Bean。
@Component("userDao") // 等效于 <bean id="userDao" class="com.bean.UserDao" />
@Autowired与@Autowired(required=false)
@Autowired 注解被扫描后,将从容器中寻找该类型的实例,如果没有找到则报错“NoSuchBeanDefinitionException”,如果使用了required=false
,则在找不到的情况下不报错其他注解
@Configuration为类注解,标注了的类为 Spring 配置类。其方法前使用了 @Bean 后,该方法的返回对象将自动被 Spring Ioc 容器管理起来。@Qualifier(“userDao”)指明容器中的一个 Bean 的 id 号
@Scope 标注 Bean 的作用域
相关代码已经同步到我的 github 项目中
参考资料: Spring 3.x 企业应用开发实战