一、使用IoC容器的方式(两种)
1. BeanFactory
- Spring 框架自用
- 延迟加载
2. ApplicationContext
- BeanFactory 的子接口
- 面向使用 Spring 框架的开发者
- 立即加载
接口定义
public interface ApplicationContext extends
EnvironmentCapable, ListableBeanFactory,
HierarchicalBeanFactory, MessageSource,
ApplicationEventPublisher, ResourcePatternResolver {
}
实现类
# 根据XML配置文件创建容器上下文
ClassPathXmlApplicationContext
# 根据注解配置文件创建容器上下文
AnnotationConfigApplicationContext
# 独立的XML应用程序上下文,从文件系统或url中获取上下文定义文件,
# 将普通路径解释为相对文件系统位置(例如:“mydir / myfile.txt”)。对于测试线束和独立环境都很有用。
FileSystemXmlApplicationContext
二、注入Bean
1. 常用依赖注入方式
setter 注入
<bean id="car1" class="com.test.spring.bean.Car"> <property name="brand" value="宝马730Li"></property> <property name="color" value="黑色"></property> <property name="price" value="870000"></property> </bean>
构造器注入
<bean id="car3" class="com.test.spring.bean.Car"> <constructor-arg value="奥迪A8" index="0"></constructor-arg> <constructor-arg value="1000000" type="java.lang.Integer"></constructor-arg> <constructor-arg value="绿色" type="java.lang.String"></constructor-arg> </bean>
接口注入(较少使用)
2. 处理 Bean 的引用关系
3. 自动装配 Bean
使用
- XML配置文件(
) - 标注注解(@Autowired)
自动装配方式
- byType 通过类型自动装配
- byName 通过名称自动装配
constructor 通过构造方法自动装配
4. Bean 的继承和依赖
继承
- Spring Bean 的继承 与 Java OOP继承 并无关系
父子 Bean
- 被继承者称为父 Bean
- 继承者称为子 Bean
- 子 Bean 从 父 Bean 中继承配置(修饰有autowire、abstract的属性不会被继承)
应用场景:如果有一些数据是公共的、通用的,可以让它成为一个父Bean,其
他Bean通过继承拿到它的配置(目的在于避免XML中的大量重复定义)
依赖
通过
depends-on
属性设定 Bean 的前置依赖 Bean,前置依赖的 Bean 会在本Bean 实例化之前创建好;可以通过逗号或空格配置多个前置Bean
5. Bean的作用域 *
Spring 中提供了五个作用域:
singleton
(单例)该作⽤域下的Bean在IoC容器中只存在⼀个实例:获取Bean(即通过applicationContext.getBean等⽅法获取)及装配Bean(即通过@Autowired注⼊)都是同⼀个对象。
prototype
(原型/多例)每次对该作⽤域下的Bean的请求都会创建新的实例
request
(请求, 限定SpringMVC中使⽤ )每次http请求会创建新的Bean实例,类似于prototype
session
(会话, 限定SpringMVC中使⽤ )在⼀个http session 会话中,定义⼀个Bean实例
global session
(全局会话, 限定SpringMVC中使⽤ )在⼀个http servlet Context中,定义⼀个Bean实例
指定方式:
- XML配置文件(
标签 - scope属性) - 注解(@Scope)
- XML配置文件(
作用域范围:prototype < request < session < global-session < singleton
6. 使用外部属性文件
- 有时需要将一些部署细节 和 Bean 配置相分离
Spring 提供了名为
PropertyPlaceholderConfigurer
的BeanFactory
后置处理器<context:property-placeholder location="classpath:db.properties"/>
引入Jar包
<dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> </dependency> <dependency
- 使用(示例)
7. SpEl表达式运用
SpEL
:Spring 表达式语言定界符
: #{…}(大框号中的字符都将被认为是 SpEL)SpEL的作用
:- 通过 Bean 的 id 对 Bean 进行引用
- 调用方法以及引用对象中的属性
- 计算表达式的值
- 正则表达式的匹配
SpEl 运用-1(字面量表达)
- 整数:
<property name="count" value="#{5}" />
- 小数:
<property name="frequency" value="#{89.7}" />
- 科学计数法:
<property name="capacity" value="#{1e4}" />
- String:(字符串的定界符 可以是单引号或双引号)
- <property name="name" value="#{'Chuck'}" />
- <property name='name' value='#{"Chuck"}' />
- Boolean:
<property name="enabled" value="#{false}" />
SpEl 运用-2(比较运算符)
- 小于:< (lt)
- 大于:>(gt)
- 等于:==(eq)
- 小于等于:<=(le)
- 大于等于:>=(ge)
<property name="equal" value="#{counter.total == 100}"/>
<property name="equalEL" value="#{counter.total le 100000}"/>
SpEl 运用-3(if-else运算符)
属于 if-else 的变体
<property name="singer" value="#{music.select() == '冷雨夜' ? ‘Beyond’: '其他'}"/> <!-- 标准写法 --> <property name="song" value="#{beyond.song != null ? beyond.song : liudehua.song}"/> <!-- 简化写法 --> <property name="song" value="#{beyond.song ?: liudehua.song}"/>
在注解中使用
// 标准写法 @Value("#{person.name != null ? person.name : 'zhangsanfeng'}") private String empName; // 简化写法 @Value("#{person.name ?: 'zhangsanfeng'}") private String empName;
SpEl 运用-4(正则表达式)
使用 matches,比如:验证邮箱格式
<property name="validEmail" value="#{user.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}'}"/>
三、Bean的生命周期 *
单例下
- Spring IoC 容器可以管理 Bean 的生命周期,允许在 Bean 生命周期的特定点执行定制的任务
IoC 容器对 Bean 的生命周期进行管理的过程:
- 1、容器启动时, 通过构造器或工厂方法创建 Bean 实例
- 2、Bean 的属性设置值和对其他 Bean 的引用
- 3、调用 Bean 的初始化方法
- 4、Bean 可以被使用
- 5、当容器关闭时, 调用 Bean 的销毁方法
实例化 => DI => 初始化 => 使用 => 销毁
在 Bean 的整个生命周期中,Spring提供了许多钩子方法,方便程序员参与管理Bean
1、InitializingBean
InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候都会执行该方法。
2、DisposableBean
DisposableBean
接口定义了一个bean销毁时的回调方法,bean销毁前会调用destroy()
方法。如果一个bean实现了该接口,当该bean被IoC容器销毁时,Spring将自动调用该方法。3、BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
BeanNameAware
、BeanClassLoaderAware
、BeanFactoryAware
接口是IoC容器向bean提供支持的方式之一,分别对应bean依赖容器的Bean名称、ClassLoader 和 BeanFactory 对象进行设置。当一个bean实现了这些接口,容器将在创建bean时自动调用相应的方法,从而将相关信息注入到bean中。4、BeanPostProcessor
BeanPostProcessor
接口允许开发者在bean的初始化前后进行一些自定义的操作,比如bean属性的修改、属性检查等。当IoC容器创建bean的时候,会自动检测是否有实现BeanPostProcessor
接口的类,如果有,就将其应用到bean的创建过程中。5、DestructionAwareBeanPostProcessor
DestructionAwareBeanPostProcessor
接口是BeanPostProcessor
接口的一个子接口,它定义了在bean销毁前需要执行的回调方法。当IoC容器销毁一个bean时,会自动检测是否有实现DestructionAwareBeanPostProcessor
接口的类,并调用其中的方法。6、BeanFactoryPostProcessor
BeanFactoryPostProcessor
接口允许开发者在IoC容器实例化任何bean之前修改bean的定义元数据。通过实现该接口,开发者可以在bean实例化前、对bean的定义进行增删改查操作,从而影响bean的创建过程。7、BeanDefinitionRegistryPostProcessor
BeanDefinitionRegistryPostProcessor
接口继承自BeanFactoryPostProcessor
接口,它主要用于对IoC容器中的BeanDefinition进行定制化处理。开发者可以通过实现该接口,在IoC容器创建之前修改BeanDefinition信息,比如添加新的BeanDefinition。8、FactoryBean
FactoryBean
接口是一个工厂bean接口,它可以创建其他的bean实例。当一个bean的定义实现了FactoryBean接口,容器在创建bean时并不是直接返回该bean实例本身,而是通过调用getObject()
方法来获取真正的bean实例。这使得开发者可以更加灵活地控制bean的创建过程。
原型下
原型下的 Bean 在每次调用的时候创建新对象, 调用完成后没使用了由GC回收