Spring学习

164 阅读4分钟

一、Spring介绍

1.1 Spring IoC 入门

  1. 导入Spring依赖
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.10.RELEASE</version>
</dependency>
  1. resource下面新建Spring配置文件applicationContext.xml
        <!-- 1. 导入 spring 的坐标 spring-context,对应版本 5.2.10.RELEASE-->
        <!-- 2. 配置bean -->
        <!--  bean 标签表示配置 bean,id 表示给 bean 起名字,class表示给 bean 定义类型-->
        <bean id="bookDao" class="com.lyq.dao.impl.BookDaoImpl"/>
        <bean id="bookService" class="com.lyq.service.impl.BookServiceImpl"/>
  1. 定义Spring管理的类(接口)
public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("book dao save ....");
    }
}
public class BookServiceImpl implements BookService {
    private BookDao bookDao = new BookDaoImpl();
    public void save (){
        System.out.println("book service save ...");
        bookDao.save();
    }
}
  1. 初始化IoC容器(Spring核心容器),通过容器获取 bean
// 3. 获取 IoC 容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
// 4. 获取 bean
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
bookDao.save();

BookService bookService = (BookService) ctx.getBean("bookService");
bookService.save();

1.2 Spring DI 入门案例

  1. 删除 Service 中 new 的对象,使用 私有变量 + set方法的形式
// 5. 删除业务层中,删除 new 创建对象
private BookDao bookDao;
public void save (){
    System.out.println("book service save ...");
    bookDao.save();
}
// 6. 提供对应 set 方法
public void setBookDao(BookDao bookDao) {
    this.bookDao = bookDao;
}
  1. 配置applicationContext.xml里面的bean,配置Service 绑定 Dao
<bean id="bookService" class="com.lyq.service.impl.BookServiceImpl">
        <!--  7. 配置 service 和 dao 关系  -->
        <!--
          property 表示配置当前的 bean 属性
          name 表示前方私有变量定义的名称
          ref 属性表示参照哪一个 bean
          -->
        <property name="bookDao" ref="bookDao"/>
</bean>

1.3 Bean 配置

1.3.1 基础配置

image.png

1.3.2 别名配置

image.png image.png

1.3.3 作用范围配置

image.png

  1. 适合交给容器管理的bean
    • 表现层对象
    • 业务层对象
    • 数据层对象
    • 工具对象
  2. 不适合交给容器管理的bean
    • 封装实体的域对象

1.4 Bean 实例化

  • 构造方法(无参)(常用)
  • 静态工厂模式 image.png
  • 实例工厂 + 工厂模式 image.png
  • 实例工厂 + 工厂模式(改良)(常用)
<bean id="userDao" class="com.lyq.factory.UserFactoryBean"/>
public class UserFactoryBean implements FactoryBean<UserDao> {
    // 代替原始实例工厂中创建对象的方法
    @Override
    public UserDao getObject() throws Exception {
        //return new UserDaoImpl();
        return null;
    }

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

1.5 Bean 生命周期

从创建到销毁的整个过程

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

1.5.1 实现生命周期的两种方式

  1. 通过在 applicationContext.xml 文件下配置 init-method 以及 destory-method 方法

applicationContext.xml

<bean id="bookDao" class="com.lyq.dao.impl.BookDaoImpl" init-method="init" destroy-method="destory"/>

实现类

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
bookDao.save();
  1. 实现InitializingBean,DisposableBean接口
public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {
    // 5. 删除业务层中,删除 new 创建对象
    private BookDao bookDao;
    public void save (){
        System.out.println("book service save ...");
        bookDao.save();
    }
    // 6. 提供对应 set 方法
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }

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

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

1.5.2 Bean 销毁时机

image.png

1.6 依赖注入方式

image.png

image.png

1.6.1 setter 注入 - 引用类型

image.png

1.6.2 setter 注入 - 普通类型

image.png

1.6.3 构造器注入 - 引用类型

image.png

1.6.4 构造器注入 - 引用类型

image.png

1.6.5 构造器注入 - 参数适配(了解)

image.png

1.6.6 依赖注入方式选择

  1. 强制依赖使用构造器进行,使用setter注入有概率不进行注入导致null对象出现
  2. 可选依赖使用setter注入进行,灵活性强
  3. Spring框架倡导使用构造器,第三方框架内部大多数采用构造器注入的形式进行数据初始化,相对严谨
  4. 如果有必要可以两者同时使用,使用构造器注入完成强制依赖的注入,使用setter注入完成可选依赖的注入
  5. 实际开发过程中还要根据实际情况分析,如果受控对象没有提供setter方法就必须使用构造器注入
  6. 自己开发的模块推荐使用setter注入

1.7 依赖自动装配

IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配

1.7.1 自动装配方式

  • 按类型(常用)
  • 按名称
  • 按构造方法
  • 不启用自动装配

image.png

1.7.2 依赖自动装配特征

  • 自动装配用于引用类型依赖注入,不能对简单类型进行操作
  • 使用按类型装配时( byType )必须保障容器中相同类型的bean唯一,推荐使用
  • 使用按名称装配时 ( byName )必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用自动装配
  • 优先级低于setter注入与构造器注入,同时出现时自动装配配置失效

案例:数据源对象管理(Spring 引入 druid)

导入 druid 依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.16</version>
</dependency>

配置 Bean

<bean  class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://10.67.181.199/maomao"/>
    <property name="username" value="application"/>
    <property name="password" value="Uts_123456"/>
</bean>

使用

public static void main(String[] args) {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    DataSource dataSource = (DataSource) ctx.getBean("dataSource");
    System.out.println(dataSource);
}

1.8 Spring 加载 properties 文件

  1. 开启context命名空间
  2. 使用context命名空间,加载properties
  3. 使用${}占位符填充
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"

       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
       
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
"
>

    <context:property-placeholder location="jdbc.properties"/>

    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <bean id="bookDao" class="com.lyq.dao.impl.BookDaoImpl">
        <property name="name" value="${jdbc.username}"/>
    </bean>
</beans>
  1. 导入properties规范写法(重要)
<context:property-placeholder location="classpath*:*.properties"/>

image.png

1.9 总结

  • 容器相关

image.png

  • Bean 相关 image.png
  • 依赖注入相关 image.png