POJO,Plain Ordinary Java Object
第一部分 Spring的核心
第二章 装配Bean
2.1 声明Bean
- 参数注入,通过构造器注入,可注入对象引用
- 通过工厂方法创建Bean
- Bean的作用域:默认是单例singleton,prototype:允许Bean的定义可以被实例化任意次(每次调用都创建一个实例)
- 初始化和销毁Bean:init-method和destroy-method,可使用
<beans>
元素的default-init-method
和default-destroy-method
配置共同的初始化和销毁方法,如下所示:
<?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"
default-init-method="turnOnLights"
default-destroy-method="turnOffLights"> ...
</beans>
- 为Bean定义初始化和销毁方法的另一种可选方式是,让Bean实现Spring的InitializingBean和DisposableBean接口。Spring容器以特殊的方式对待实现这两个接口的Bean,允许它们进入Bean的生命周期。
2.2 注入bean属性
- 注入简单值
- 引用其他Bean
- 注入内部Bean
内部Bean是定义在其他Bean内部的Bean,不能被复用,不能被其他Bean所引用。内部Bean不仅限于setter注入,还可以把内部Bean装配到构造方法的入参中。
<bean id="kenny"
class="com.springinaction.springidol.Instrumentalist">
<property name="song" value="Jingle Bells" />
<property name="instrument">
<bean class="org.springinaction.springidol.Saxophone" />
</property>
</bean>
<bean id="duke"
class="com.springinaction.springidol.PoeticJuggler">
<constructor-arg value="15" />
<constructor-arg>
<bean class="com.springinaction.springidol.Sonnet29" />
</constructor-arg>
</bean>
- 使用Spring命名空间p装配属性
- 装配集合
Collection element | Useful for |
---|---|
<list> | Wiring a list of values, allowing duplicates |
<set> | Wiring a set of values, ensuring no duplicates |
<map> | Wiring a collection of name-value pairs where name and value can be of any type |
<props> | Wiring a collection of name-value pairs where the name and value are both Strings |
- 装配空值
为属性设置null值,只需使用<null/>
元素。
<property name="someNonNullProperty"><null/></property>
2.3 使用表达式装配
- Spring表达式语言(Spring Expression Language, SpEL)
- #{}标记其内容是SpEL表达式
- SpEL支持正则表达式
- 可使用SpEL筛选集合、访问集合成员、查询集合成员、投影集合(从集合的每一个成员中选择特定的属性放入一个新的集合中)。
- 思考:是否可替代应用的配置项???
第三章 最小化Spring XML配置
- 自动装配(autowiring)
有助于减少甚至消除配置<property>
元素和<constructor-arg>
元素,让Spring自动识别如何装配Bean的依赖关系。 - 自动检测(autodiscovery)
比自动装配更进一步,让Spring能够自动识别哪些类需要被配置成Spring Bean,从而减少对<bean>
元素的使用。
3.1 自动装配Bean属性
- 4种类型的自动装配
类型 | 说明 |
---|---|
byName | 相同名字(或者ID),属性装配 |
byType | 相同类型,属性装配 |
constructor | 相同类型,构造器装配 |
autodetect | 先constructor,如失败使用byType |
- 首选Bean(默认primary的值为true)、取消某个Bean的自动装配的候选资格
- 默认自动装配
可在根元素<beans>
增加default-autowire
属性标示所有Bean的默认自动装配类型,但是<bean>
中的autowire
属性可以覆盖<beans>
元素所配置的默认自动装配策略。 - 混合使用自动装配和显示装配
注意事项:当使用constructor自动装配策略时,我们必须让Spring自动装配构造器的所有入参——我们不能混合使用constructor自动装配策略和<constructor-arg>
元素。
3.2 使用注解装配
Spring容器默认禁用注解装配。在Spring的context命名空间中配置<context:annotation-config>
启用自动装配功能,如下所示:
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<!-- bean declarations go here -->
</beans>
- @Autowired
byType方式,不仅可标注setter方法,还可以标注需要自动装配Bean引用的任意方法,甚至可以标注构造器及属性。可通过配置required属性配置自动装配是可选的。当使用构造器装配时,只有一个构造器可以将required属性设置为true。
如下所示:
@Autowired
public void setInstrument(Instrument instrument) {
this.instrument = instrument;
}
@Autowired
public void heresYourInstrument(Instrument instrument) {
this.instrument = instrument;
}
@Autowired
public Instrumentalist(Instrument instrument) {
this.instrument = instrument;
}
@Autowired(required=false)
private Instrument instrument;
- @Qualifier
限定歧义性的依赖,byName装配。可创建自定义的限定器。 - @Inject
Java依赖注入规范,和@Autowired一样,@Inject可以用来自动装配属性、方法和构造器;与@Autowired不同的是,@Inject没有required属性。因此,@Inject主键所标注的依赖关系必须存在,如果不存在,则会抛出异常。@Inject可以注入一个Provider,可以实现Bean引用的延迟注入以及注入Bean的多个实例等功能。 - @Named
类似于Spring的@Qualifier,通过Bean的ID来标识可选择的Bean。实际上,@Named注解就是一个使用@Qualifier注解所标注的注解。 - 使用javax.inject.Qualifier创建自定义的JSR-330 Qualifier
- 在注解注入中使用表达式
3.3 自动检测Bean
为了配置Spring自动检测,使用<context:component-scan>
元素来代替<context:annotation-config>
元素,第一个元素除了完成与第二个元素一样的工作外,还允许Spring自动检测Bean和定义Bean。如下所示:
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan
base-package="com.springinaction.springidol">
</context:component-scan>
</beans>
- 为自动检测标注Bean
@Component、@Controller、@Repository、@Service,其中@Component比较常用,可以在标注是指定一个Bean ID作为注解的参数。 - 过滤组件扫描
通过<context:include-filter>
和<context:excludefilter>
可以随意调整扫描行为。
3.4 使用Spring基于Java的配置
几乎不是有XML而使用纯粹的Java代码类配置Spring应用。
- 创建基于Java的配置
- 定义一个配置类
等价于XML配置中的<beans>
元素。 - 声明一个简单的Bean
- 使用Spring的基于Java的配置进行注入
第4章 面向切面的Spring
AOP(Aspect Oriented Programming),面向切面编程。
4.1 什么是面向切面编程
- AOP述语
通知(Advice)、连接点(JoinPoint)、切点(Pointcut)、切面(Aspect)、引入(Introduction)、织入(Weaving) - Spring通知是Java编写的
- Spring在运行期通知对象
Spring的切面由包裹了目标对象的代理类实现,代理类处理方法的调用,执行额外的切面逻辑,并调用目标方法。 - Spring只支持方法连接点
4.2 使用切点选择连接点
- 编写切点
- 使用Spring的bean()指示器
该指示器允许在切点表达式中使用Bean的ID来标识Bean。bean()使用Bean ID或Bean名称作为参数来限制切点只匹配特定的Bean。
4.3 在XML中声明切面
- 声明前置、后置和环绕通知
- 为通知传递参数
- 通过切面引入新功能
使用Spring AOP,我们可以为Bean引入新的方法,代理拦截调用并委托给实现该方法的的其他对象。
4.4 注解切面
通过@AspectJ,可以将类转换为一个切面,可注解前置、后置、环绕通知。
4.5 注入AspectJ切面
虽然Spring AOP能够满足许多应用的切面需求,但与AspectJ相比,Spring AOP是一个功能比较弱的AOP解决方案。AspectJ提供了Spring AOP所不能支持的许多类型的切点。