一、使用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)
  • 作用域范围:prototype < request < session < global-session < singleton

6. 使用外部属性文件

  • 有时需要将一些部署细节 和 Bean 配置相分离
  • Spring 提供了名为 PropertyPlaceholderConfigurerBeanFactory 后置处理器

    <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

      BeanNameAwareBeanClassLoaderAwareBeanFactoryAware 接口是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回收

最后修改:2023 年 12 月 09 日
如果觉得我的文章对你有用,请点个赞吧~