文章目录
- [🌍一. 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 创建的顺序是什么? 并分析执行流程
- 先创建 id=memberDAOImpl
- 再创建 id = memberServiceImpl
- 调用 memberServiceImpl.setMemberDAO() 完成引用
4.先看下面的配置, 请问两个 bean 创建的顺序是什么, 并分析执行流程
- 先创建 id = memberServiceImpl
- 再创建 id=memberDAOImpl
- 用 memberServiceImpl.setMemberDAO() 完成引用
🌍二. bean 对象的单例和多例
❄️1. 机制
在 spring 的 ioc 容器, 在默认是按照单例创建的,即配置一个 bean 对象后,ioc 容器只会创建一个 bean 实例。
如果,我们希望 ioc 容器配置的某个 bean 对象,是以多个实例形式创建的则可以通过配置scope="prototype"
来指定
- 在 spring 的 ioc 容器, 在默认情况下是安装单例创建的,即配置一个 bean 对象后,
ioc 容器只会创建一个 bean 实例。 - 如果,我们希望 ioc 容器配置的某个 bean 对象,
是以多个实例形式创建的则可以通过配置 scope="prototype" 来指定
xml
<bean name="car" scope="prototype" class="com.hspedu.spring.beans.Car"/>
❄️2. 使用细节
- 默认是单例 singleton, 在启动容器时, 默认就会创建 , 并放入到 singletonObjects 集合
- 当 设置为多实例机制后, 该 bean 是在 getBean()时才创建
- 如 果 是 单 例 singleton, 同 时 希 望 在 getBean 时 才 创 建 , 可 以 指 定 懒 加 载
lazy-init="true" (注意默认是 false) - 通常情况下, lazy-init 就使用默认值 false , 在开发看来, 用空间换时间是值得的, 除非有特殊的要求.
- 如果 scope="prototype" 这时你的 lazy-init 属性的值不管是 ture, 还是 false 都是在getBean 时候,才创建对象.
🌍三. bean 的生命周期
说明: bean 对象创建是由 JVM 完成的,然后执行如下方法
- 执行构造器
- 执行 set 相关方法
- 调用 bean 的初始化的方法(需要配置)
- 使用 bean
- 当容器关闭时候,调用 bean 的销毁方法(需要配置)
1.init-method="init" 指定bean的初始化方法 , 在setter方法后执行
init方法执行的时机,有spring容器来控制
destroy-method="destroy" 指定bean的销毁方法, 在容器关闭的时候执行
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 的后置处理器 【这个比较难】
- 在 spring 的 ioc 容器,可以配置 bean 的后置处理器
- 该处理器/对象会在 bean 初始化方法调用前和初始化方法调用后被调用
- 程序员可以在后置处理器中编写自己的代码
xml
<bean id="myBeanPostProcessor" class="com.hspedu.spring.beans.MyBeanPostProcessor" />
</beans>
1、怎么执行到这个方法?=> 使用 AOP(反射+动态代理+IO+容器+注解)
2、有什么用?=>
可以对 IOC 容器中所有的对象进行统一处理 ,比如 日志处理/权限的校验/安全的验证/事务管理
3、针对容器的所有对象吗?
是的=>切面编程特点
🌍五. 通过属性文件给 bean 注入值
- 通过属性文件给 bean 注入值, 2. 需要导入: xmlns:context 名字空间,并指定属性文件路径
1.先把这个文件修改成提示All Problem
提示错误,将光标放在context 输入alt+enter 就会自动引入namespace
location="classpath:my.properties" 表示指定属性文件的位置
提示,需要带上 classpath
属性文件有中文,需要将其转为unicode编码-> 使用工具
6.通过属性文件给monster对象的属性赋值
这时我们的属性值通过${属性名}
这里说的 属性名 就是 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时通过类型的方式 给对象属性 自动完成赋值/引用
比如OrderService 对象有 private OrderDao orderDao
就会在容器中去找有没有 OrderDao类型对象
如果有,就会自动的装配, 老师提示如果是按照 byType 方式来装配, 这个容器中,不能有两个的OrderDao类型对象
如果你的对象没有属性, autowire就没有必要写
其它类推.
7.如果我们设置的是 autowire="byName" 表示通过名字完成自动装配比如下面的 autowire="byName" class="com.hspedu.spring.service.OrderService"
先看 OrderService 属性 private OrderDao orderDao
再根据这个属性的setXxx()方法的xxx来找对象id
public void setOrderDao() 就会找id=orderDao对象来进行自动装配
如果没有就装配失败
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 表达式[知道即可]
- Spring Expression Language,Spring 表达式语言,简称 SpEL。支持运行时查询并可以操作对象。
- 和 EL 表达式一样,SpEL 根据 JavaBean 风格的 getXxx()、setXxx()方法定义的属性访问对象
- SpEL 使用#{...}作为定界符,所有在大框号中的字符都将被认为是 SpEL 表达式。
- 不是重点,如果看到有人这样使用,能看懂即可
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>