Spring Framework系统架构

核心概念

  • 代码书写现状
    • 耦合度偏高
  • 解决方案
    • 使用对象时,在程序种不要主动使用new产生对象。转换为由外部提供对象
  • Ioc(Inversion of Control)控制反转
    • 对象的创建控制权由程序转移到外部,这种思想称为控制反转
  • spring技术对Ioc思想进行了实现
    • Spring提供了一个容器,称为Ioc容器,用来充当Ioc思想的外部
    • Ioc容器负责对象的创建、初始化等一系列工作,被创建或管理的对象在Ioc容器种统称为bean
  • DI(dependency Injection)依赖注入
    • 在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入
  • 目标:充分解耦
    • 使用Ioc容器管理bean(Ioc)
    • 在Ioc容器内将有依赖关系的bean进行绑定(DI)
  • 最终效果
    • 使用对象时不仅可以直接从Ioc容器中获取,并且获取到的bean已经绑定了所有的依赖关系

Ioc入门案例思路分析

  1. 管理什么?(Service与dao)
  2. 如何将被管理的对象告知Ioc容器?(配置)
  3. 被管理的对象交给Ioc容器,如何获取到Ioc容器?(接口)
  4. Ioc容器得到后,如何从容器中获取bean?(接口方法)
  5. 使用Spring导入哪些坐标?(pom,xml)

步骤 Ioc入门案例(XMl版)

  1. 导入Spring坐标

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>5.2.10.RELEASE</version>
            </dependency>
    
  2. 定义Spirng管理的类(接口)

    public interface BookService {
        void save();
    }
    
    public class BookDaoImpl implements BookDao {
        @Override
        public void save() {
            System.out.println("book dao save....");
        }
    }
    
  3. 创建Spring配置文件,配置对应类作为Spring管理的bean

    • 注意事项:bean定义时id属性在同一个上下文中不能重复
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
        <!--导入spring的坐标spring-context,对应版本是5.2.10.RELEASE-->
    
        <!--2.配置bean
        bean标签标示配置bean
        id属性标示给bean起名字
        class属性标示给bean定义类型-->
        <bean id="bookDaoImpl" class="com.xhj.dao.impl.BookDaoImpl"/>
        <bean id="bookServiceImpl" class="com.xhj.service.impl.BookServiceImpl"/>
    </beans>
    
  4. 初始化Ioc容器(Spring核心容器/Spring容器),通过容器获取bean

    public static void main(String[] args) {
            //获取IOC容器
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            //获取bean
            BookService bookServiceImpl = context.getBean("bookServiceImpl",BookService.class);
            bookServiceImpl.save();
        }
    

DI入门案例

DI入门案例思路分析

  1. 基于Ioc管理bean
  2. Service中使用new的形式创建Dao对象是否保留?(否)
  3. Service中需要Dao对象如何进入到Service中?(提供方法)
  4. Servcice与Dao之间的关系如何描述?(配置)

步骤 DI入门案例(XML版)

  1. 删除使用new的形式创建对象的代码
public class BookServiceImpl implements BookService {
    private BookDao bookDao;
    @Override
    public void save() {
        bookDao.save();
        System.out.println("book service save.....");
    }

    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }
}
  1. 提供依赖对象对应的setter方法
public void setBookDao(BookDao bookDao) {
    this.bookDao = bookDao;
}
  1. 配置serivce与dao之间的关系
<bean id="bookDaoImpl" class="com.xhj.dao.impl.BookDaoImpl"/>
<bean id="bookServiceImpl" class="com.xhj.service.impl.BookServiceImpl">
    <property name="bookDao" ref="bookDaoImpl"/>
</bean>

bean配置

bean基本配置

bean别名配置

bean作用范围配置

bean作用范围说明

  • 为什么bean默认为单例?
  • 时候交给容器进行管理的bean
    • 表现层对象
    • 业务层对象
    • 数据层对象
    • 工具对象
  • 不适合交给容器进行管理的bean
    • 封装实体的域对象

bean实例化

bean是如何创建的

  • bean本质上就是对象,创建bean使用构造方法完成

实例化bean的三种方式---构造方法(常用)

  • 无参构造方法如果不存在,将抛出一场BeanCreateException

实例化bean的三种方式---静态工厂(了解)

实例化bean的三种方式---实例工厂(了解)

实例化bean的第四种方式---FactoryBean(实用)

bean生命周期

  • 生命周期:从创建到消亡的完整过程
  • bean生命周期:bean从创建到消亡的整体过程
  • bean生命周期控制:在bean创建后到销毁前做一些事情

生命周期控制

  • 提供生命周期控制方法

    public class BookDaoImpl implements BookDao {
        @Override
        public void save() {
            System.out.println("book dao save....");
        }
    
        void init() {
            System.out.println("初始化....");
        }
    
        void destroy() {
            System.out.println("销毁....");
        }
    
    }
    
  • 配置说明周期控制方法

    <bean id="bookDaoImpl" class="com.xhj.dao.impl.BookDaoImpl" init-method="init" destroy-method="destroy"/>
    

bean生命周期控制——控制接口(了解)

  • 实现InitializingBean, DisposableBean接口

    public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {
        private BookDao bookDao;
        @Override
        public void save() {
            bookDao.save();
            System.out.println("book service save.....");
        }
    
        public void setBookDao(BookDao bookDao) {
            this.bookDao = bookDao;
        }
    
        @Override
        public void destroy() throws Exception {
            System.out.println("service destroy");
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("afterPropertiesSet");
        }
    }
    
  • 初始化容器
    1. 创建对象(内存分配)
    2. 执行构造方法
    3. 执行属性注入(set操作)
    4. 执行bean初始化方法
  • 使用bean
    1. 执行业务操作
  • 关闭/销毁容器
    1. 执行bean销毁方法

bean销毁时机

  • 容器关闭前触发bean的销毁
  • 关闭容器方式
    • 手工关闭容器
      • ConfigableApplicaotionContext接口close()操作
    • 注册关闭钩子
      • ConfigableApplicaotionContext接口registerShutdownHook()操作