2022-09-27 spring

spring

前言

代码书写现状

耦合度偏高

解决方案

使用对象时,在程序上不要主动使用new产生对象,转换为由外部提供对象

概念

IoC(Inversion of Control)控制反转

使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部,此思想称为控制反转

  • spring技术对IoC思想进行了实现
  • spring提供了一个容器,称为IoC容器,用来充当IoC思想中的“外部”
  • IoC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中统称为Bean

DI(Dependency Injection)依赖注入

在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入

目标

充分解耦

  • 使用IoC容器管理bean(IoC)
  • 在IoC容器内将有依赖关系的bean进行关系绑定(DI)

最终效果

使用对象时不仅可以直接从IoC容器中获取,并且获取到的bean已经绑定了所有的依赖关系

步骤

  1. 导入spring的坐标spring-context,对应版本是5.2.10.RELEASE
  2. 配置bean

bean标签表示配置bean
id属性表示给bean起名字
class属性表示给bean定义类型

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"></bean>

<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"></bean>
  1. 获取IoC容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
  1. 获取bean
BookService bookService = (BookService) ctx.getBean("bookService");
  1. 删除业务层中使用new的方式创建的Dao对象
private BookDao bookDao;
  1. 提供对应的set方法
public void setBookDao(BookDao bookDao) {
    this.bookDao = bookDao;
}
  1. 配置service与dao的关系
    property标签表示配置当前bean的属性
    name属性表示参照哪一个bean
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"></bean>

<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">

    <property name="bookDao" ref="bookDao"></property>
</bean>

bean

别名

定义bean的别名,可定义多个,使用逗号(,)分号(;)空格( )分隔

<bean id="bookService" name="service service2 bookEbi" class="com.itheima.service.impl.BookServiceImpl"></bean>

注意:获取bean无论是通过id还是name获取,如果无法获取到,将抛出异常NoSuchBeanDefinitionException

bean的配置

创建出来的对象时非单例的

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" scope="prototype"></bean>

创建单例的对象

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" scope="singleton"></bean>

默认是单例的

适合交给容器进行管理的bean

  • 表现层对象
  • 业务层对象
  • 数据层对象
  • 工具对象

不适合交给容器进行管理的bean

  • 封装实体的域对象

bean实例化

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

实例化bean的三种方式

构造方法
  • 提供可访问的构造方法
  • 无参构造方法如果不存在,将抛出异常BeanCreationException(bean创建异常)
静态工厂(了解)
  • 静态工厂
public class OrderDaoFactory {
   public static OrderDao getOrderDao(){
       return new OrderDaoImpl();
   }
}
  • 配置
<bean id="orderDao" class="com.itheima.factory.OrderDaoFactory" factory-method="getOrderDao"></bean>
实例工厂(了解)
  • 实例工厂
public class UserDaoFactory {
    public UserDao getUserDao(){
        return new UserDaoImpl();
    }
}
  • 配置
<bean id="userFactory" class="com.itheima.factory.UserDaoFactory"></bean>

<bean id="userDao" factory-method="getUserDao" factory-bean="userFactory"></bean>
实例化bean的第四种方式-----FactoryBean(实用)
  • FactoryBean
public class UserDaoFactoryBean implements FactoryBean<UserDao> {
    // 代替原始实例工厂中创建对象的方法
    public UserDao getObject() throws Exception {
        return new UserDaoImpl();
    }

    public Class<?> getObjectType() {
        return UserDao.class;
    }

}
  • 配置
<bean id="userDao" class="com.itheima.factory.UserDaoFactoryBean"></bean>

bean的生命周期

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

  • 初始化容器
    1. 创建对象(内存分配)
    2. 执行构造方法
    3. 执行属性注入(set操作)
    4. 执行bean初始化方法
  • 使用bean
    1. 执行业务操作
  • 关闭/销毁容器
    1. 执行bean销毁方法

提供生命周期控制

  • 提供生命周期控制方法
public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("book dao save...");
    }
    // 表示bean初始化对应的操作
    public void init(){
        System.out.println("init...");
    }
    // 表示bean销毁前对应的操作
    public void destory(){
        System.out.println("destory...");
    }
}
  • 配置生命周期控制方法
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" init-method="init" destroy-method="destory"></bean>

接口控制(了解)

public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {
    private BookDao bookDao;

    public void save() {
        System.out.println("book service save...");
    }
    public void setBookDao(BookDao bookDao) {
        System.out.println("set...");
        this.bookDao = bookDao;
    }

    public void destroy() throws Exception {
        System.out.println("service destroy");
    }

    public void afterPropertiesSet() throws Exception {
        System.out.println("service init");
    }
}

bean销毁时机

  • 容器关闭前触发bean的销毁
  • 关闭容器方式:
    • 手工关闭容器
      ConfigurableApplicationContext接口close()操作
    • 注册关闭钩子,在虚拟机退出前先关闭容器再退出虚拟机
      ConfigurableApplicationContext接口registerShutdownHook()操作
public class AppForLifeCycle {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        ctx.close();
        ctx.registerShutdownHook();  // 第二种方法
    }
}
posted @ 2022-09-28 10:26  LegendR  阅读(19)  评论(0)    收藏  举报