| IOC 思想基于 IOC 容器完成,IOC 容器底层就是对象工厂 |
种类 | Spring 提供 IOC 容器实现两种方式:(两个接口)
BeanFactory | - IOC 容器基本实现,是 Spring 内部的使用接口,不提供开发人员进行使用
- 加载配置文件时候不会创建对象,在获取对象(使用)才去创建对象 (懒汉式)
| ApplicationContext | - BeanFactory 接口的子接口,提供更多更强大的功能,一般由开发人员进行使用
- 加载配置文件时候就会把在配置文件对象进行创建(饿汉式)
|
- 这里使用饿汉式比较好
- 即使懒加载可以节省内存空间,但是由于很多IOC容器管理的对象都是经常使用的,所以并没有节省多少时间
- 饿汉式的好处在于把加载(初始化)类的时间放到了整个服务器初始化的时候,等服务器运行时就可以立刻使用到需要的IOC对象,而不像懒加载那样等待初始化完成才可以使用
|
IOC底层原理
2021年3月3日
20:37
IOC概念 | spring ioc指的是控制反转,IOC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。交由Spring容器统一进行管理,从而实现松耦合
依赖对象 | 依赖关系,是类与类之间的联接。依赖关系表示一个类依赖于另一个类的定义。一般情况下,依赖关系在Java语言中体现为局域变量、方法的形参,或者对静态方法的调用。
- 比如类A中有一个域对象B,则A依赖于B(A想要创建对象时,必须先创建域对象B)
在IOC中,上例的B也是一个对象,
|
|
目的 | 降低耦合度 |
IOC底层技术 | xml解析、工厂模式、反射 |
背景 |
|
流程图 | 
|
系统文件 | demo.class
baseDao.class
Utils.class |
模拟IOC | |
demo结构 | 目录结构 | 描述 | 
| annotation | SelfAutowired | 模拟IOC中@Autowired的注解,使用在一个类(该类由IOC管理)的域的上面,且该域对象也是由IOC进行管理 | SelfService | 自定义注解,模拟ioc的@Service注解, 在一个类声明前使用该注解时,表示运行时,该类注册在IOC容器中,由IOC进行管理 |
| IOC | 这个类模仿学习Spring_IOC的功能 | Servlet_1\2\3 | 用来模拟Servlet程序(类声明前都打上了@SelfService的标签),其中servlet_3的执行依赖于servlet_1和servlet_1

| test | 测试文件夹,用来进行junit测试 | Utils | - 这个class工具类用来扫描一个package下的所有类,并返回class对象,路径为默认src为开始目录
- 里面还有一个方法可以扫描jar包里面的类,但是要提供jar包的路径,以及jar包里面package的路径
|
|
|

文件名(类名)
io读取

调用
List<Class<?>> package路径下所有类的类对象
调用

IOC容器
放入新建对象
调用

| 
|
|
- 对beans容器中所有的对象进行执行依赖检查,并对有执行依赖的类进行赋值
|

| 
|
获取类属性 | 
|
遍历判断 |
判断条件 | 
| 成功 | 
| 失败 | 直接退出 |
|
调用

完成依赖注入

程序视图
调用
用户视图
十、
调用构造方法,完成IOC初始化
域的初始化
调用getBean()获得对象
IOC bean 配置
2021年3月3日
20:38
XML管理方式
2021年3月9日
20:11
基于 xml 配置文件方式实现
2021年3月6日
19:53
配置 | |
标签属性 | 属性 | 描述 | Id | - 对被IOC管理的对象起一个唯一标识,面向的是使用者
Bean中一个id对应一个唯一的对象
- 当然可以通过多个互不相同的id,相同的类全名,来配置多个同类的对象
| class | 类全路径(包类路径) | name | 用来为id创建一个或多个别名,它可以是任意的字母符合。多个别名之间用逗号, 分号 或者空格分开。 | index | index:第几个参数,用在bean<>的子标签中(比如constructor-arg),表示这个标签所代表的参数在方法的参数列表中的位置(从0开始),用来准确的选择到对应的构造方法 |
|
配置文件格式示例 | <bean id="id_1" class="com.huz.Service.Servlet_1"> </bean> |
|
依赖注入 | DI:依赖注入,就是注入属性
- 属性注入要求该类需要遵守bean典范,即需要有get方法
|
手动注入 | 调用方法注入 | - 即调用对象的get与set方法来完成对属性的赋值与修改
| 构造器注入 | - new一个对象的时候,使用有参数的构造器进行属性的注入
|
|
配置文件注入 | |
<bean>标签注入 | 方式 | 在 spring 配置文件配置对象的bean标签中,通过在标签中添加键值对的方式进行,属性注入 | 格式 | <bean id="id_1" class="com.huz.Service.Servlet_1">
<!--bean标签包围property标签,property标签以键值对的方式进行赋值-->
<property name="field_name1" value="value_1"></property>
<property name="field_name1" value="value_2"></property>
</bean> |
| 示例 | 
| 效果 | 执行Getbean()后,获得的对象中对应的域被设置为bean标签所设置的值 |
字面量注入 | null 值 | 格式 | <!--null 值-->
<property name="field_name">
<null/>
</property> |
| 示例 | 
|
| 属性值包含特殊符号 | 格式 | <property name="field_name" >
<value><![CDATA[ <<container>> ]]></value>
</property> |
| | 
|
|
| 注入bean | 注入外部bean | 定义 | - 在配置域中通过id注入(引用)一个已经在IOC容器中的对象
| 格式 | <property name="field_name" ref="引用对象的id值">
</property> |
| 示例 | 
|
| 注入内部bean |
定义 | - 在配置域中注入一个临时新建的对象(该对象在域的属性标签内部用bean标签嵌套创建)
- 匿名是因为外部变量没有引用此对象,只有此域引用了这个对象
| 格式 | <property name="outer_field">
<!--outer_field域注入一个匿名的id为object_id的com.huz.bean.department类对象-->
<bean id="object_id" class="com.huz.bean.department">
<property name="field_name" value="value">
</property>
</bean>
</property> |
| 示例 | 
|
|
|
| 级联赋值 | | 假设域A要引用B这个对象,则
| 方式一 | 方式 | 先在外部创建B,在B外部的创建tag内设置好该B的域,再对A进行外部注入(引用 | 示例 | 
|
| 方式二 | 方式 | - 先在外部创建B,再对A进行外部注入,注入后直接在A的内部修改B的域
- 即在<bean>标签中通过id值设置其他bean的属性值
| 格式 | name="other_object'id.field_name" |
| | 
|
|
| 注入集合属性 | 类型 | 格式 | 数组注入 | <!--数组注入-->
<property name="array">
<array>
<value>value_1</value>
<value>value_2</value>
<value>value_3</value>
<value>value_4</value>
</array>
</property> |
| List注入 | <!--List注入-->
<property name="list">
<list>
<value>value_1</value>
<value>value_2</value>
<value>value_3</value>
<value>value_4</value>
</list>
</property> |
| map注入 | <!--map注入-->
<property name="map">
<map>
<entry key="key_1" value="value_1"></entry>
<entry key="key_2" value="value_2"></entry>
<entry key="key_3" value="value_3"></entry>
</map>
</property> |
| set注入 | <property name="set">
<set>
<value>value_1</value>
<value>value_2</value>
<value>value_3</value>
<value>value_4</value>
</set>
</property> |
| 集合里面设置对象类型值 | <!--通过id对集合注入对象-->
<property name="list_Object">
<list>
<ref bean="id_1"></ref>
<ref bean="id_2"></ref>
<ref bean="id_3"></ref>
<ref bean="id_4"></ref>
</list>
</property>
<!--被集合引用的对象-->
<bean id="id_1" class="com.huz.bean.employee"></bean>
<bean id="id_2" class="com.huz.bean.employee"></bean>
<bean id="id_3" class="com.huz.bean.employee"></bean>
<bean id="id_4" class="com.huz.bean.employee"></bean |
|
| 集合注入部分的提取 | 概念 | - 即在外部声明集合元素,在内部(用集合的id)进行引用注入,而不是直接在内部声明
| 修改名称空间为util | | 外部集合的声明 | <!--util后面为集合的类型,可以是set和map,id为声明此集合的id以便引用-->
<util:list id="list_1">
<value>value_1</value>
<value>value_2</value>
<value>value_3</value>
<value>value_4</value>
</util:list> |
| 在域中注入外部集合 | <!--集合对象的外部引用注入-->
<bean id="collection_2" class="com.huz.bean.collection">
<property name="list" ref="list_1">
</property>
</bean> |
|
|
|
有参构造注入 | 方式 | 通过在配置文件中,列出要调用的构造器的参数和值的方式,调用该类的某一个构造器,从而进行属性注入 | 格式 | <bean id="id_2" class="com.huz.Service.Servlet_1">
<!--bean标签包围pconstructor-ar标签,配置文件会去匹配符合参数列表的构造器进行创建对象-->
<constructor-arg name="parameter_1" value="value_1"></constructor-arg>
<constructor-arg name="parameter_2" value="value_2"></constructor-arg>
</bean> |
| 实例 | 配置 | 
| 调用的构造器 | 
|
|
|
p 名称空间注入 | 说明 | - 使用 p 名称空间注入,可以简化基于 xml 配置方式
- 将<property> 子元素 简化为 bean标签的元素的属性
| 步骤 | 添加 | xmlns:p="http://www.springframework.org/schema/p" |

| 注入 | - 直接在标签内进行属性注入,在 bean 标签里面进行操作
格式 | p:<属性名>="value" //引入常量值
p:<属性名>-ref="引用bean的id值" //引用其它Bean对象 |
|
| 示例 |
|
|
|
自动装配(xml自动装配)
2021年3月6日
20:34
概念 | 根据指定装配规则(属性名称或者属性类型),Spring 自动将匹配的属性值进行注入 |
使用 | 通过在<bean>标签中声明autowire属性来开启自动装配,通过设置autowire的值来设置自动装配的方式 |
属性 | autowire的值 | 搜索范围 | 匹配规则 | byName | 同一个配置文件下的所有bean | - 寻找其他bean的id值是否和自己域中的任意一个域的名称相同,
- 若是,则把这个bean注入到自己相同的那个的域中
| byType | 同一个配置文件下的所有bean | - 寻找其他bean的类型是否和自己域中的任意一个域的类名相同,
- 若是,则把这个bean注入到自己相同的那个的域中
|
|
匹配事项 | - 不管是byName、byType两个都只能匹配一个对象,若匹配时有多个对象可匹配,则报错
|
示例 | byName装配 | 
| byType装配 | 
|
|
外部属性文件
2021年3月9日
20:11
原始方式 | 
|
缺点 | - 所有的配置项目(属性)都集中在了同一个配置文件中,修改时比较麻烦
- 当程序员需要只把部分属性暴露出来给用户自行设置时,原始方式不能满足
|
外部属性文件 | - 在主配置文件中并不直接进行配置,而是引用外部文件的配置
- 即把一个bean标签的配置项都分散在不同的文件中,以实现配置分类管理的需求
|
使用 | 引入 context 名称空间 | | 引入外部属性文件 | <!--引入外部属性文件,路径开始位置为classpath(src)-->
<context:property-placeholder location="classpath:jdbc.properties"/> |
| 填充主文件中的属性 | - 在value属性中不再直接填入具体值,而是通过$的形式来代表一个外部值
主文件 | 以便于区分 | 外部文件 | | 效果 | value的值为root |
|
|
示例 | 
|
注解管理方式
2021年3月9日
19:35
注解 | 注解是代码特殊标记格式 |
格式 | @注解名称(属性名称=属性值, 属性名称=属性值..) |
|
使用范围 | 作用在类上面,方法上面,属性上面 |
目的 | 简化 xml 配置 |
准备步骤 | 添加依赖包 | 
| 指定注解扫描的路径 |
<context:component-scan base-package="com.huz">
</context:component-scan> |
- 扫描的是指定的目录下所有类(包括子包下的类)
- 使用时,要读入该配置文件,再去getBean

| 使用注解 | |
|
注解创建对象
2021年3月9日
21:44
创建对象 | Spring 针对 Bean 管理中创建对象提供注解 |
种类 | 注解 | 建议使用的类 | @Component | | @Service | 一般用在业务层 | @Controller | 一般用在表现层 | @Repository | 一般用在持久层 |
- 上面四个注解功能是一样的(可以混用),都可以用来创建 bean 实例
|
使用 | @Component ( vlaue = "自定义id名") //其他标签类似 |
|
使用示例 |
- 在注解里面 value 属性值可以省略不写(即只写@Component), 不写时,默认值是类名的首字母小写
|
注解注入属性
2021年3月9日
21:44
| 功能 | 根据属性类型进行自动装配 | 规则 | 若一个域的声明前标记了该注释,
- 若该域是一个类,则Spring会在IOC容器中查找和该域同一个类的对象,注入到该域中
- 若该域是一个接口,则Spring会在IOC容器中查找一个实现了该接口的对象,并把实现类对象赋值给该域
| 操作 | - 为主对象标记添加对象注释
- 为要注入的对象添加创建对象注释
- 在主对象内部标记要注入的域
| 示例 | 情景 | 在Service类中通过注释注入Dao实现类 | 注入的主对象 | 
| 被注入的对象 | 
|
|
|
| 功能 | - 和上面@Autowired 一起使用,功能变为根据名称(bean标签中id的值)进行注入
- 因为一般根据属性类型进行自动装配会有多个结果(比如一个接口可能由多个实现类),则可以通过id值,指定唯一的对象,而不是交给机器来随机选择
| 格式 | @Qualifier(value = "配置bean的id值") |
| 示例 | 
|
|
| 功能 | 可以根据类型注入,可以根据名称注入 | 格式 | @Resource // 不写name是类型注入
@Resource(name = "配置的bean的id值") //写name的是名称注入 |
| 示例 | 
|
|
| 功能 | 直接在域声明前,注入普通类型属性 | 格式 | | 示例 | 
|
|
完全注解开发
2021年3月10日
19:11
原来做法 | - 需要在xml中配置context外部空间并且读入xml文件才能使用注解的管理方式,但是context还是需要在xml中进行配置
|
完全注释开发 | 不需要任何xml配置文件,完成注解开发 |
使用 | 自定义创建配置类,替代 xml 配置文件 | @Configuration //此标签表明 此类是Spring的配置类
@ComponentScan (basePackages = {"扫描路径"})
//此注释相当于配置注释的扫描范围,也是从calsspath(src目录开始)
public class SpringConfig //类名可以自己定义
{
//里面不用写代码
} |
| 加载配置类 | 
|
|
示例 | 
|
bean
2021年3月7日
21:22
概述 | Spring 有两种类型 bean
- 一种普通 bean
- 另外一种工厂 bean(FactoryBean)
|
| 普通 bean | 在配置文件中定义 bean 类型就是返回类型 | 工厂 bean | - 在配置文件定义 bean 类型可以和返回类型不一样
- FactoryBean 通常是用来创建比较复杂的bean,一般的bean直接用xml配置即可
- 如果一个bean的创建过程中涉及到很多其他的bean和复杂的逻辑,用xml配置比较困难,这时可以考虑用FactoryBean,通过编写方法的形式去完成一个类的加载。
|
|
FactoryBean 使用示例
2021年3月7日
20:38
xml配置文件 | 
|
bean对象创建

否
是,调用
getObject()
调用方法
转换对象 | 
|



放入
放入
获取bean_b
获取bean_a
注意事项 | - 即使配置的时候是bean_a,由于容器中最终放入的对象
已经转化成了bean_b
- 所以在使用视角,要把此Object看成bean_b类对象
|
bean的作用域
2021年3月7日
21:22
概述 | - 在 Spring 里面,可以设置创建 bean 实例是单实例还是多实例
- 在 Spring 里面,默认情况下,bean 是单实例对象
|
设置方法 | 方法 | - 在配置文件对应的bean的<bean Scope="" >标签中设置scope字段值来设置是单例还是多例
| 字段 | scope属性值 | 意义 | | 默认值,表示是单实例对象 | | 表示是多实例对象 |
|
|
单实例 | 定义 | - 每次getbean()后返回的对象都是同一个对象
- 加载 spring 配置文件时候就会创建单实例对象
| 配置 | 
| 执行代码 | 
| 效果 | 
|
|
多实例 | 定义 | - 每次getbean()后返回的对象都是不同的对象
- 不是在加载 spring 配置文件时候创建对象,在调用 getBean 方法时候创建多实例对象
- 原来bean设置与FactoryBean是否多例的关系:
| 配置 | 
| 执行代码 | 
| 效果 | 
|
|
bean生命周期
2021年3月7日
22:18
定义 | 从对象创建到对象销毁的过程 |
阶段 | 实例化 Instantiation | 通过构造器创建 bean 实例(Spring调用无参数构造) | 属性赋值 Populate | 为 bean 的属性设置值和对其他 bean 引用(Spring调用 set 方法) | 初始化 Initialization | 调用 bean 的初始化的方法(需要自己声明初始化方法并把方法名配置到配置文件中) | | bean 可以使用了(对象获取到了) | 销毁 Destruction | 当容器关闭时候,需要程序员手动调用 bean 的销毁的方法(需要自己声明初始化方法并把方法名配置到配置文件中) | | 主要逻辑都在doCreate()方法中,逻辑很清晰,就是顺序调用以下三个方法
createBeanInstance() | 实例化 | populateBean() | 属性赋值 | initializeBean() | 初始化 |
| 源码部分 |
销毁,是在容器关闭时调用的,详见ConfigurableApplicationContext#close() |
|
方法实现
| 自定义初始化方法 | 方式 | | 格式 | <!-- InitMethod_name:为自己声明的初始化方法的方法名-->
<bean name="id" class="class'spackage"
init-method="InitMethod_name">
</bean> |
| 运行 | |
| 自定义销毁方法 | 方式 | | 格式 | <!-- destroyMethod_name 为自己声明的销毁方法的方法名-->
<bean name="id" class="class'spackage"
destroy-method="destroyMethod_name">
</bean> |
| 运行 | - 当调用下列String的销毁方法时,该配置的销毁方法会被String自动调用
FileSystemXmlApplicationContext.close
ClassPathXmlApplicationContext.close
- 当调用close之后,该ApplicationContext所读入的配置文件中的所有创建的bean都会被销毁
|
|
|
常用扩展点 | |
影响多个Bean的接口 | 种类 | 类名 | 作用时机 | InstantiationAwareBeanPostProcessor | 实例化阶段的前后 | BeanPostProcessor | 初始化阶段的前后 |
| 图例 | 
| 使用 | 实现 | - 单独创建一个类(处理类),此类专门用来实现InstantiationAwareBeanPostProcessor、BeanPostProcessor接口中处理bean的方法

| 绑定 | 
|
|
|
周期图 | 
|
Interface BeanFactory
2021年3月6日
19:20
Info | |
Fields | |
Constructor | |
Method Summary | | | <T> T | getBean(Class<T> requiredType)
Return the bean instance that uniquely matches the given object type, if any. | <T> T | getBean(Class<T> requiredType, Object... args)
Return an instance, which may be shared or independent, of the specified bean. | Object | getBean(String name)
Return an instance, which may be shared or independent, of the specified bean. | <T> T | getBean(String name, Class<T> requiredType)
Return an instance, which may be shared or independent, of the specified bean. | Object | getBean(String name, Object... args)
Return an instance, which may be shared or independent, of the specified bean. |
|
Interface ApplicationContext
2021年3月6日
19:28
Info | |
Fields | |
Constructor | |
Method Summary | |
Class ClassPathXmlApplicationContext
2021年3月6日
19:31
Info | Standalone XML application context, taking the context definition files from the class path |
Fields | |
Constructor | Constructor | ClassPathXmlApplicationContext(String configLocation)
- Create a new ClassPathXmlApplicationContext, loading the definitions from the given XML file and automatically refreshing the context.
configLocation |
|
|
|
Method Summary | Methods inherited from class org.springframework.context.support.AbstractApplicationContext
close |
Class FileSystemXmlApplicationContext
2021年3月6日
19:31
Info | |
Fields | |
Constructor | Constructor | | FileSystemXmlApplicationContext(String configLocation)
Create a new FileSystemXmlApplicationContext, loading the definitions from the given XML file and automatically refreshing the context.
configLocation | 
|
|
|
Method Summary | Methods inherited from class org.springframework.context.support.AbstractApplicationContext
close |
Class AnnotationConfigApplicationContext
2021年3月10日
19:32
Info | |
Fields | |
Constructor | AnnotationConfigApplicationContext(Class<?>... componentClasses)
Create a new AnnotationConfigApplicationContext, deriving bean definitions from the given component classes and automatically refreshing the context. |
Method Summary | |
Interface FactoryBean<T>
2021年3月7日
21:59
Info | |
Fields | |
Constructor | |
Method Summary | |
Interface InstantiationAwareBeanPostProcessor
2021年3月10日
19:34
Info | |
Fields | |
Constructor | |
Method Summary | |
Interface BeanPostProcessor
2021年3月10日
19:36
Info | |
Fields | |
Constructor | |
Method Summary | | | default Object | postProcessAfterInitialization(Object bean, String beanName)
Apply this BeanPostProcessor to the given new bean instance after any bean initialization callbacks (like InitializingBean's afterPropertiesSet or a custom init-method). | default Object | postProcessBeforeInitialization(Object bean, String beanName)
Apply this BeanPostProcessor to the given new bean instance before any bean initialization callbacks (like InitializingBean's afterPropertiesSet or a custom init-method) |
|