IOC概念和原理

  1. 什么是IOC:
    (1)控制反转,把对象创建和对象之间的调用过程,交给Spring进行管理。
    (2)使用IOC的目的就是为了降低耦合度。
  1. IOC底层原理
  • xml解析
  • 工厂模式
  • 反射

image-20210822161230097工厂模式
工厂模式
IOC模式过程
创建对象和属性注入—通过xml文件配置
1.IOC思想基于IOC容器完成,IOC容器底层就是对象工厂
2.Spring提供IOC容器的实现的两种方式(两个接口):
1)BeanFactory:IOC容器基本实现,是Spring内部的使用接口
加载配置文件时不创建对象,在使用对象时才创建对象
2)ApplicationContext:BeanFactory接口的子接口,提供更多更强大的功能
加载配置文件时自动创建对象bean
开发过程中一般使用ApplicationContext方式实现IOC容器
在项目启动时就将所有对象bean加载并创建

IOC操作Bean管理

1.什么是Bean管理?
Spring创建对象,Spring注入属性
2.Bean管理操作有两种方式:
1)基于xml配置文件方式
2)基于注解方式

基于xml方式

xml方式创建对象

  1. <!-- 配置User对象创建 -->
  2. <bean id="user" class="com.abao.spring5.User"></bean>
  3. 1)在Spring配置文件中,使用bean标签,标签里添加对应属性,就可以实现对象创建
  4. 2)在bean标签里有很多属性,介绍常用的属性
  5. * id属性:唯一标识-->
  6. * class 类的全路径-->
  7. 3)创建对象的时候,默认执行类的无参构造方法完成对象创建
  8. `注意:spring在创建对象时会默认调动无参构造方法`

xml方式注入属性

  1. DI:依赖注入,就是注入属性(spring创建对象时将对象的属性进行赋值)

set方法注入

  1. User类:
  2. public class User {
  3. private String userName;
  4. public void setUserName(String userName) {
  5. this.userName = userName;
  6. }
  7. }
  8. xml配置:
  9. <bean id="user" class="com.abao.spring5.User">
  10. <property name="userName" value="张三"></property>
  11. </bean>

有参构造方式

  1. User
  2. public class User {
  3. private String userName;
  4. public User(String userName){
  5. this.userName=userName;
  6. }
  7. }
  8. xml配置:
  9. <!-- 配置User对象创建 -->
  10. <bean id="user" class="com.abao.spring5.User">
  11. <constructor-arg name="userName" value="张三"/>
  12. </bean>

xml方式注入其他属性

注入null与特殊符号

  1. 字面量:设置属性的固定值(默认值)
  2. 1null
  3. <bean id="user" class="com.abao.spring5.User">
  4. <property name="userName">
  5. <null/>
  6. </property>
  7. </bean>
  8. 2)特殊符号
  9. <bean id="user" class="com.abao.spring5.User">
  10. <property name="userName">
  11. <value><![CDATA[<<南京>>]]></value>
  12. </property>
  13. </bean>
  14. 也可以设置转义字符&lt

注入外部bean

  1. <bean id="userDao" class="com.abao.spring5.dao.UserDaoImpl"></bean>
  2. <bean id="userService" class="com.abao.spring5.service.UserService">
  3. <!-- name:属性名 ref:创建userDao对象bean标签的id -->
  4. <property name="userDao" ref="userDao"></property>
  5. </bean>

注入内部bean

  1. <bean id="emp" class="com.abao.spring5.bean.Emp">
  2. <property name="ename" value="张三"></property>
  3. <property name="gender" value="男"></property>
  4. <property name="dept">
  5. <bean id="dept" class="com.abao.spring5.bean.Dept">
  6. <property name="dname" value="开发部"></property>
  7. </bean>
  8. </property>
  9. </bean>

注入属性–级联赋值

  1. <bean id="dept" class="com.abao.spring5.bean.Dept">
  2. <property name="dname" value="开发部"></property>
  3. </bean>
  4. <bean id="emp" class="com.abao.spring5.bean.Emp">
  5. <property name="ename" value="张三"></property>
  6. <property name="gender" value="男"></property>
  7. <property name="dept" ref="dept"></property>
  8. <!-- 此方式需要设置dname的Getter方法 -->
  9. <property name="dept.dname" value="开发部"></property>
  10. </bean>

注入集合类型属性1

  1. <bean id="emp" class="com.abao.spring5.bean.Stu">
  2. <!-- 数组类型 courses:课程数组-->
  3. <property name="courses">
  4. <array>
  5. <value>java课程</value>
  6. <value>vue课程</value>
  7. <value>react课程</value>
  8. </array>
  9. </property>
  10. <!-- List集合 -->
  11. <property name="list">
  12. <list>
  13. <value>张三</value>
  14. <value>李四</value>
  15. <value>王五</value>
  16. </list>
  17. </property>
  18. <!-- Map集合 -->
  19. <property name="maps">
  20. <map>
  21. <entry key="zhangsan" value="张三"></entry>
  22. <entry key="lisi" value="李四"></entry>
  23. </map>
  24. </property>
  25. <!-- Set集合 -->
  26. <property name="sets">
  27. <set>
  28. <value>张三</value>
  29. <value>李四</value>
  30. <value>王五</value>
  31. </set>
  32. </property>
  33. </bean>

注入集合类型属性2

  1. 方式一:
  2. <!-- List集合 -->
  3. <bean id="dept1" class="com.abao.spring5.bean.Dept">
  4. <property name="dname" value="开发部"></property>
  5. </bean>
  6. <bean id="dept2" class="com.abao.spring5.bean.Dept">
  7. <property name="dname" value="运维部"></property>
  8. </bean>
  9. <property name="depts">
  10. <list>
  11. <ref bean="dept1"></ref>
  12. <ref bean="dept2"></ref>
  13. </list>
  14. </property>
  1. 方式二:
  2. `注意此方法需要引入util命名空间`
  3. <!-- List集合抽取 -->
  4. <beans xmlns="http://www.springframework.org/schema/beans"
  5. xmlns:util="http://www.springframework.org/schema/util"
  6. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  7. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  8. http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
  9. <util:list id="names" >
  10. <value>张三</value>
  11. <value>李四</value>
  12. <value>王五</value>
  13. </util:list>
  14. <bean id="user" class="com.abao.spring5.bean.User">
  15. <property name="names" ref="names"></property>
  16. </bean>
  17. </beans>

Factory Bean

  1. 1.Spring 有两种Bean,一种普通bean,另一种工厂beanFactoryBean
  2. 1)普通bean:在配置文件中定义的类型就是返回的类型
  3. 如以下配置中定义的bean类型为User类,spring创建对象类型也为User对象
  4. <bean id="user" class="com.abao.spring5.bean.User">
  5. <property name="names" ref="names"></property>
  6. </bean>
  7. 2)工厂bean:在配置文件中定义的类型与返回类型不同
  8. 第一步:创建类,让这个类作为bean并实现FactoryBean
  9. 第二步:实现接口里的方法,在实现的方法中定义返回bean的类型
  10. <bean id="myBean" class="com.abao.spring5.bean.MyBean"></bean>
  11. 实际返回为User类对象如以下代码段:
  1. package com.abao.spring5;
  2. import org.springframework.beans.factory.FactoryBean;
  3. /**
  4. * @author abao
  5. * @date 2021-01-14 22:42
  6. */
  7. public class MyBean implements FactoryBean<User> {
  8. //定义返回bean
  9. @Override
  10. public User getObject() throws Exception {
  11. User user = new User();
  12. user.setUserName("张三");
  13. return user;
  14. }
  15. @Override
  16. //定义返回bean类型
  17. public Class<?> getObjectType() {
  18. return User.class;
  19. }
  20. //是否单例实例
  21. @Override
  22. public boolean isSingleton() {
  23. return true;
  24. }
  25. }

Bean作用域

xml

  1. 1)单实例(默认)
  2. <bean id="user" class="com.abao.spring5.User" scope="singleton"></bean>
  3. 2)多实例
  4. <bean id="user" class="com.abao.spring5.User" scope="prototype"></bean>
  5. 单实例就是用单例模式创建bean对象,无论获取多少次bean对象都是同一个对象
  6. 多实例就是每次获取bean对象都会创建新的bean对象
  7. 两种方式的创建时机也不同,单例(singleton)在bean初始化自动创建,多实例则在获取bean对象时创建

Bean生命周期

shell

  1. 1.生命周期:从对象的创建到对象的销毁的过程。
  2. 2.Bean的生命周期
  3. 1)通过构造器创建bean实例(无参构造)
  4. 2)为bean的属性赋值和对其他bean的引用
  5. 3)调用bean的初始化方法(需要进行配置)
  6. 4bean就可以使用了(获取到bean对象)
  7. 5)当容器关闭时,调用bean的销毁方法(需要进行配置)
  8. <bean id="user" class="com.abao.spring5.User" scope="prototype" init-method="initMethod" destroy-method="destroyMethod">
  9. <property name="userName">
  10. <null/>
  11. </property>
  12. </bean>
  13. public void initMethod(){
  14. Console.log("初始化方法被调用");
  15. }
  16. public void destroyMethod(){
  17. Console.log("销毁方法被调用");
  18. }

image-20210115202228973
image-20210115202228973
xml

  1. bean的后置处理器,必须实现 BeanPostProcessor接口
  2. bean 初始化之前、初始化之后
  3. 如下配置,会为所有bean对象都添加后置处理器
  4. <bean id="myBeanPost" class="com.abao.spring5.MyBeanPost"></bean>

image-20210115220222054
image-20210115220222054

xml自动装配

shell

  1. 1.什么是自动装配?
  2. 1)根据指定装配规则(属性名称或者属性类型),Spring自动将匹配的属性值进行注入。
  3. User类中有deptDept类)属性
  4. <bean id="user" class="com.abao.spring5.User" autowire="byName">
  5. </bean>
  6. <bean id="dept" class="com.abao.spring5.bean.Dept">
  7. <property name="dname" value="开发部"></property>
  8. </bean>
  9. 注意:Dept类的bean中的id必须与User中的dept属性名一样
  10. autowire="byName""byType"
  11. byType是根据类型进行匹配,自动装配一般很少用到。

引入外部属性文件

shell

  1. 应用场景:
  2. 方式一:在bean.xml中直接配置数据库连接池信息,如下图:

image-20210115223110907
image-20210115223110907
shell

  1. 方式二:bean.xml中引入数据库连接池的外部配置文件

创建jdbc.properties文件
image-20210115223357387
image-20210115223357387
引入contex命名空间
image-20210115223457860
image-20210115223457860
在bean.xml中引入外部属性文件,如下图:
image-20210115223622772
image-20210115223622772
在bean.xml中使用表达式引用外部属性文件的value,如下图:
image-20210115223712761

基于注解方式