【spring02】Spring 管理 Bean-IOC,基于 XML 配置 bean

文章目录

    • [🌍一. bean 创建顺序](#🌍一. bean 创建顺序)
    • [🌍二. bean 对象的单例和多例](#🌍二. bean 对象的单例和多例)
      • [❄️1. 机制](#❄️1. 机制)
      • [❄️2. 使用细节](#❄️2. 使用细节)
    • [🌍三. bean 的生命周期](#🌍三. bean 的生命周期)
    • [🌍四. 配置 bean 的后置处理器 【这个比较难】](#🌍四. 配置 bean 的后置处理器 【这个比较难】)
    • [🌍五. 通过属性文件给 bean 注入值](#🌍五. 通过属性文件给 bean 注入值)
    • [🌍六. 基于 XML 的 bean 的自动装配](#🌍六. 基于 XML 的 bean 的自动装配)
    • [🌍七. spring el 表达式[知道即可]](#🌍七. spring el 表达式[知道即可])

🙋‍♂️ 作者:@whisperrr.🙋‍♂️

👀 专栏:spring👀

💥 标题:【spring01】Spring 管理 Bean-IOC,基于 XML 配置 bean💥

❣️ 寄语:比较是偷走幸福的小偷❣️

🌍一. bean 创建顺序

1.在 spring 的 ioc 容器, 默认是按照配置的顺序创建 bean 对象

xml 复制代码
<bean id="student01" class="com.hspedu.bean.Student" />
<bean id="department01" class="com.hspedu.bean.Department" />

会先创建 student01 这个 bean 对象,然后创建 department01 这个 bean 对象

2.如果这样配置

xml 复制代码
<bean id="student01" class="com.hspedu.bean.Student" depends-on="department01"/>
<bean id="department01" class="com.hspedu.bean.Department" />

会先创建 department01 对象,再创建 student01 对象.

3.先看下面的配置, 请问两个 bean 创建的顺序是什么? 并分析执行流程

  1. 先创建 id=memberDAOImpl
  2. 再创建 id = memberServiceImpl
  3. 调用 memberServiceImpl.setMemberDAO() 完成引用

4.先看下面的配置, 请问两个 bean 创建的顺序是什么, 并分析执行流程

  1. 先创建 id = memberServiceImpl
  2. 再创建 id=memberDAOImpl
  3. 用 memberServiceImpl.setMemberDAO() 完成引用

🌍二. bean 对象的单例和多例

❄️1. 机制

在 spring 的 ioc 容器, 在默认是按照单例创建的,即配置一个 bean 对象后,ioc 容器只会创建一个 bean 实例。

如果,我们希望 ioc 容器配置的某个 bean 对象,是以多个实例形式创建的则可以通过配置scope="prototype" 来指定

  1. 在 spring 的 ioc 容器, 在默认情况下是安装单例创建的,即配置一个 bean 对象后,
    ioc 容器只会创建一个 bean 实例。
  2. 如果,我们希望 ioc 容器配置的某个 bean 对象,
    是以多个实例形式创建的则可以通过配置 scope="prototype" 来指定
xml 复制代码
<bean name="car" scope="prototype" class="com.hspedu.spring.beans.Car"/>

❄️2. 使用细节

  1. 默认是单例 singleton, 在启动容器时, 默认就会创建 , 并放入到 singletonObjects 集合
  2. 当 设置为多实例机制后, 该 bean 是在 getBean()时才创建
  3. 如 果 是 单 例 singleton, 同 时 希 望 在 getBean 时 才 创 建 , 可 以 指 定 懒 加 载
    lazy-init="true" (注意默认是 false)
  4. 通常情况下, lazy-init 就使用默认值 false , 在开发看来, 用空间换时间是值得的, 除非有特殊的要求.
  5. 如果 scope="prototype" 这时你的 lazy-init 属性的值不管是 ture, 还是 false 都是在getBean 时候,才创建对象.

🌍三. bean 的生命周期

说明: bean 对象创建是由 JVM 完成的,然后执行如下方法

  1. 执行构造器
  2. 执行 set 相关方法
  3. 调用 bean 的初始化的方法(需要配置)
  4. 使用 bean
  5. 当容器关闭时候,调用 bean 的销毁方法(需要配置)

1.init-method="init" 指定bean的初始化方法 , 在setter方法后执行

  1. init方法执行的时机,有spring容器来控制

  2. destroy-method="destroy" 指定bean的销毁方法, 在容器关闭的时候执行

  3. destroy方法执行的时机,有spring容器来控制

xml 复制代码
<bean id="house" class="com.hspedu.spring.beans.House"
init-method="init" destroy-method="destory">
<property name="name" value="北京豪宅"/>
</bean>

5.初始化 init 方法和 destory 方法, 是程序员来指定

6.销毁方法就是当关闭容器时,才会被调用.

🌍四. 配置 bean 的后置处理器 【这个比较难】

  1. 在 spring 的 ioc 容器,可以配置 bean 的后置处理器
  2. 该处理器/对象会在 bean 初始化方法调用前和初始化方法调用后被调用
  3. 程序员可以在后置处理器中编写自己的代码
xml 复制代码
<bean id="myBeanPostProcessor" class="com.hspedu.spring.beans.MyBeanPostProcessor" />
</beans>

1、怎么执行到这个方法?=> 使用 AOP(反射+动态代理+IO+容器+注解)

2、有什么用?=>

可以对 IOC 容器中所有的对象进行统一处理 ,比如 日志处理/权限的校验/安全的验证/事务管理

3、针对容器的所有对象吗?

是的=>切面编程特点

🌍五. 通过属性文件给 bean 注入值

  1. 通过属性文件给 bean 注入值, 2. 需要导入: xmlns:context 名字空间,并指定属性文件路径

1.先把这个文件修改成提示All Problem

  1. 提示错误,将光标放在context 输入alt+enter 就会自动引入namespace

  2. location="classpath:my.properties" 表示指定属性文件的位置

  3. 提示,需要带上 classpath

  4. 属性文件有中文,需要将其转为unicode编码-> 使用工具

6.通过属性文件给monster对象的属性赋值

  1. 这时我们的属性值通过${属性名}

  2. 这里说的 属性名 就是 my.properties文件中的 k=v 的k

xml 复制代码
<context:property-placeholder location="classpath:my.properties"/>
<bean id="monster100" class="com.hspedu.spring.beans.Monster">
<property name="monsterId" value="${id}"/>
<property name="name" value="${name}"/>
<property name="skill" value="${skill}"/>
</bean>

🌍六. 基于 XML 的 bean 的自动装配

1.autowire="byType" 表示 在创建 orderService时通过类型的方式 给对象属性 自动完成赋值/引用

  1. 比如OrderService 对象有 private OrderDao orderDao

  2. 就会在容器中去找有没有 OrderDao类型对象

  3. 如果有,就会自动的装配, 老师提示如果是按照 byType 方式来装配, 这个容器中,不能有两个的OrderDao类型对象

  4. 如果你的对象没有属性, autowire就没有必要写

  5. 其它类推.
    7.如果我们设置的是 autowire="byName" 表示通过名字完成自动装配

  6. 比如下面的 autowire="byName" class="com.hspedu.spring.service.OrderService"

  1. 先看 OrderService 属性 private OrderDao orderDao

  2. 再根据这个属性的setXxx()方法的xxx来找对象id

  3. public void setOrderDao() 就会找id=orderDao对象来进行自动装配

  4. 如果没有就装配失败

xml 复制代码
 <!--配置OrderDao对象-->
    <bean class="com.hspedu.spring.dao.OrderDao" id="orderDao"/>
    <bean autowire="byName" class="com.hspedu.spring.service.OrderService"
          id="orderService"/>
    <bean autowire="byName" class="com.hspedu.spring.web.OrderAction" id="orderAction"/>

🌍七. spring el 表达式[知道即可]

  1. Spring Expression Language,Spring 表达式语言,简称 SpEL。支持运行时查询并可以操作对象。
  2. 和 EL 表达式一样,SpEL 根据 JavaBean 风格的 getXxx()、setXxx()方法定义的属性访问对象
  3. SpEL 使用#{...}作为定界符,所有在大框号中的字符都将被认为是 SpEL 表达式。
  4. 不是重点,如果看到有人这样使用,能看懂即可
xml 复制代码
<!-- spring el 表达式 -->
<bean id="spELBean" class="com.hspedu.spring.beans.SpELBean">
<!-- sp el 给字面量 -->
<property name="name" value="#{'韩顺平教育'}"/>
<!-- sp el 引用其它 bean -->
<property name="monster" value="#{monster01}"/>
<!-- sp el 引用其它 bean 的属性值 -->
<property name="monsterName" value="#{monster02.name}"/>
<!-- sp el 调用普通方法 赋值 -->
<property name="crySound" value="#{spELBean.cry('喵喵的..')}"/>
<!-- sp el 调用静态方法 赋值 -->
<property name="bookName" value="#{T(com.hspedu.spring.beans.SpELBean).read(' 天龙八部')}"/>
<!-- sp el 通过运算赋值 -->
<property name="result" value="#{89*1.2}"/>
</bean>
相关推荐
程序员小假16 小时前
我们来说一下 MySQL 的慢查询日志
java·后端
独自破碎E17 小时前
Java是怎么实现跨平台的?
java·开发语言
To Be Clean Coder17 小时前
【Spring源码】从源码倒看Spring用法(二)
java·后端·spring
xdpcxq102917 小时前
风控场景下超高并发频次计算服务
java·服务器·网络
想用offer打牌17 小时前
你真的懂Thread.currentThread().interrupt()吗?
java·后端·架构
橘色的狸花猫17 小时前
简历与岗位要求相似度分析系统
java·nlp
独自破碎E17 小时前
Leetcode1438绝对值不超过限制的最长连续子数组
java·开发语言·算法
用户917439653918 小时前
Elasticsearch Percolate Query使用优化案例-从2000到500ms
java·大数据·elasticsearch
yaoxin52112318 小时前
279. Java Stream API - Stream 拼接的两种方式:concat() vs flatMap()
java·开发语言
坚持学习前端日记18 小时前
2025年的个人和学习年度总结以及未来期望
java·学习·程序人生·职场和发展·创业创新