初识Spring -- Spring快速入门保姆级教程(一)(2)

简介: 初识Spring -- Spring快速入门保姆级教程(一)

5.spring 中 bean的实例化–构造方法

  1. 创建新的maven模块respr_newbean,并在pom.xml添加spring的坐标

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.22</version>
            <scope>compile</scope>
        </dependency>
  1. 创建核心配置文件applicationContext.xml文件、dao接口及其实现类以及相关的类(先写标记部分)

  1. 编写dao接口及其实现类
  • BookDao接口
public interface BookDao {
    public void save();
}
  • BookDaoImpl实现类
public class BookDaoImpl implements BookDao {
    //无参构造
    public BookDaoImpl() {
        System.out.println("book dao constructor is running ....");
    }
    public void save() {
        System.out.println("book dao save ...");
    }
}
  • 进行测试的类 AppForInstanceBook
public class AppForInstanceBook {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
        bookDao.save();
    }
}
  • applicationContext.xml
<?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">
    <!--方式一:构造方法实例化bean-->
    <bean id="bookDao" class="org.example.dao.impl.BookDaoImpl"/>
</beans>
  • AppForInstanceBook运行结果

  • 结论

spring构造方法实例化bean使用了无参构造器,可以省略无参构造器的书写。实例化bean就是用构造方法来实例化对象。

6.bean的实例化 – 静态工厂实例化

  1. 创建dao接口及其实现类以及相关的类(先写标记部分)

  1. 编写dao接口及其实现类以及相关的类
  • OrderDao接口
package org.example.dao;
public interface OrderDao {
    public void save();
}
  • OrderDaoImpl实现类
在这里插入代码片package org.example.dao.impl;
import org.example.dao.OrderDao;
public class OrderDaoImpl implements OrderDao {
    public void save() {
        System.out.println("order dao save ...");
    }
}
  • 工厂类OrderDaoFactory(静态工厂类代理生成对象)
package org.example.factory;
import org.example.dao.OrderDao;
import org.example.dao.impl.OrderDaoImpl;
//静态工厂创建对象
public class OrderDaoFactory {
    public static OrderDao getOrderDao(){
        System.out.println("factory setup....");
        return new OrderDaoImpl();
    }
}
  • AppForInstanceOrder模拟测试类编写(纯JAVA开发,此处还没有Spring)
public class AppForInstanceOrder {
    public static void main(String[] args) {
        //通过静态工厂创建对象
        OrderDao orderDao = OrderDaoFactory.getOrderDao();
        orderDao.save();
    }
}
  • 模拟测试类的运行结果

  • 简要分析

将 OrderDaoImpl 创建对象的 工作交给 静态工厂 OrderDaoFactory 类来完成,如果用spring代理这种工厂模式的开发,写法如下

  • spring 代理静态工厂实例化对象
public class AppForInstanceOrder {
    public static void main(String[] args) {
        //通过静态工厂创建对象
//        OrderDao orderDao = OrderDaoFactory.getOrderDao();
//        orderDao.save();
//      spring代理静态工厂实例化对象
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        OrderDao orderDao = (OrderDao) ctx.getBean("orderDao");
        orderDao.save();
    }
}
  • applicationContext.xml文件配置静态工厂 OrderDaoFactory bean (注意factory-method属性)
<?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">
    <!--方式一:构造方法实例化bean-->
<!--    <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>-->
<!--    方式二:使用静态工厂实例化bean-->
    <bean id="orderDao" class="com.itheima.factory.OrderDaoFactory" factory-method="getOrderDao"/>
</beans>
  • 运行结果

7.bean实例化–实例工厂和FactoryBean

  1. 创建dao接口及其实现类以及相关的类(标记部分)

  1. 编写dao接口及其实现类以及相关的类
  • UserDao接口
public interface UserDao {
    public void save();
}
  • UserDaoImpl实现类
public class UserDaoImpl implements UserDao {
    public void save() {
        System.out.println("user dao save ...");
    }
}
  • UserDaoFactoryBean实例工厂类
//实例工厂创建对象
public class UserDaoFactory {
    public UserDao getUserDao(){
        return new UserDaoImpl();
    }
}
  • AppForInstanceUser模拟测试类(纯JAVA开发)
public class AppForInstanceUser {
    public static void main(String[] args) {
//        //创建实例工厂对象
        UserDaoFactory userDaoFactory = new UserDaoFactory();
//        //通过实例工厂对象创建对象
        UserDao userDao = userDaoFactory.getUserDao();
        userDao.save();
    }
}
  1. 运行结果

  1. 简要分析

此时与静态工厂的区别是模拟测试类中多了创建工厂对象的步骤

  • spring代理下的实例工厂bean实例化模拟测试类
public class AppForInstanceUser {
    public static void main(String[] args) {
//        //创建实例工厂对象
//        UserDaoFactory userDaoFactory = new UserDaoFactory();
//        //通过实例工厂对象创建对象
//        UserDao userDao = userDaoFactory.getUserDao();
//        userDao.save();
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = (UserDao) ctx.getBean("userDao");
        userDao.save();
    }
}
  1. applicationContext.xml(分辨方式二和方式三的写法)
<?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">
    <!--方式一:构造方法实例化bean-->
    <!--    <bean id="bookDao" class="org.example.dao.impl.BookDaoImpl"/>-->
    <!--    方式二:使用静态工厂实例化bean-->
<!--    <bean id="orderDao" class="org.example.factory.OrderDaoFactory" factory-method="getOrderDao"/>-->
    <!--方式三:使用实例工厂实例化bean-->
        <bean id="userFactory" class="org.example.factory.UserDaoFactory"/>
        <bean id="userDao" factory-method="getUserDao" factory-bean="userFactory"/>
</beans>
  1. 模拟测试类运行结果

  1. spring代理实例工厂bean实例化简要分析 --> 改进为BeanFactory bean实例化

  1. 创建并编写BeanFactory工厂类UserDaoFactoryBean
//FactoryBean创建对象
//实现接口,创建什么对象写什么泛型
public class UserDaoFactoryBean implements FactoryBean<UserDao> {
    //实现抽象方法
    //代替原始实例工厂中创建对象的方法,以后方法名不用指定,就用getObject
    public UserDao getObject() throws Exception {
        return new UserDaoImpl();
    }
    //配置的类是什么类型
    public Class<?> getObjectType() {
        return UserDao.class;
    }
}
  1. 配置applicationContext.xml文件
<?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">
    <!--方式一:构造方法实例化bean-->
    <!--    <bean id="bookDao" class="org.example.dao.impl.BookDaoImpl"/>-->
    <!--    方式二:使用静态工厂实例化bean-->
<!--    <bean id="orderDao" class="org.example.factory.OrderDaoFactory" factory-method="getOrderDao"/>-->
    <!--方式三:使用实例工厂实例化bean-->
<!--        <bean id="userFactory" class="org.example.factory.UserDaoFactory"/>-->
<!--        <bean id="userDao" factory-method="getUserDao" factory-bean="userFactory"/>-->
    <!--方式四:使用FactoryBean实例化bean-->
    <bean id="userDao" class="org.example.factory.UserDaoFactoryBean"/>
</beans>
  1. 模拟测试类运行结果

8.bean的生命周期

  1. 概念

  • 理解 Spring bean 的生命周期很容易。当一个 bean 被实例化时,它可能需要执行一些初始化使它转换成可用状态。同样,当 bean 不再需要,并且从容器中移除时,可能需要做一些清除工作
  • 尽管还有一些在 Bean 实例化和销毁之间发生的活动,有两个重要的生命周期回调方法,它们在 bean 的初始化销毁的时候是必需的
  • 为了定义安装和拆卸一个 bean,我们只要声明带有 init-method 和/或 destroy-method 参数的 。init-method 属性指定一个方法,在实例化 bean 时,立即调用该方法。同样,destroy-method 指定一个方法,只有从容器中移除 bean 之后,才能调用该方法
  • Bean的生命周期可以表达为:Bean的定义——Bean的初始化——Bean的使用——Bean的销毁
  1. 编写代码(IOC 和 DI入门案例的代码,模块名为respr_ioc)
  • 在BookDaoImpl实现类中定义代表创建bena初始化和销毁的方法
package org.example.dao.impl;
import org.example.dao.BookDao;
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...");
    }
}
  1. 在applicationContext.xml文件中配置BookDao bean 的 初始化方法 int-method 和销毁方法 destory-method

  1. 将BookService的代码注释掉,运行模拟测试类,观察BookDao bean的创建和销毁过程

  • 运行结果

  1. 简要分析
    我们从运行结果可以看到bean初始化成功了,但是并没有进行销毁工作,原因是java虚拟机(java在虚拟机运行)在执行玩程序退出时并没有做销毁操作,我们需要自己添加关闭语句,ctx.close()。但是ApplicationContext接口中并没有这个方法,而它的实现类中有,所以我们要用它的实现类ClassPathXmlApplicationContext来调用这个方法
  2. 关闭ioc容器的代码及运行结果如下

  1. 关闭ioc容器的第二种方式:关闭钩子(概念、代码及运行结果如下)

在Java程序退出时——尤其是非正常退出时,我们可能需要先执行一些善后工作,如关闭线程池、连接池、文件句柄等。如何保证善后工作的代码能够被执行到呢?Java为用户提供了关闭钩子(shutdown hook)registerShutdownHook()方法来注册关闭钩子

  1. 两种关闭ioc容器的简要分析
    关闭钩子函数代码在程序中的位置要求没有close()方法那么苛刻,如果将其挪到bookDao.save()方法的下面也能用,close()方法比较暴力
  2. 绑定销毁方法和初始化方法的改进–继承接口(以BookServiceImpl为例)
  • 实现InitializingBean, DisposableBean接口
  • 重写 destroy(销毁) 和 afterPropertiesSet(初始化) 方法
public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {
    private BookDao bookDao;
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }
    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
    public void destroy() throws Exception {
        System.out.println("service destroy");
    }
    public void afterPropertiesSet() throws Exception {
        System.out.println("service init");
    }
}
  1. 模拟测试类Main2运行结果

(尽管在模拟测试类Main2并没有调用BookService 的bean,但是在核心配置文件中定义了BookService 的 bean,该创建bean的时候就创建,该初始化就初始化,该销毁就销毁)

9.依赖注入 – setter注入

  1. 思考

  1. 依赖注入 – setter注入引用类型的步骤方法(DI入门案例所用的就是setter注入引用类型)

(代码见DI入门案例)

  1. 探讨引用多个引用对象(在DI入门的代码基础上编码)
  • 在dao包下创建并编写UserDao接口
package org.example.dao;
public interface UserDao {
    public void save();
}
  • 在impl包下创建并编写UserDaoImpl实现类
package org.example.dao.impl;
import org.example.dao.UserDao;
public class UserDaoImpl implements UserDao {
    public void save() {
        System.out.println("user dao save ...");
    }
}
  • 在BookServiceImpl实现类中setter注入UserDao
public class BookServiceImpl implements BookService{
    private BookDao bookDao;
    private UserDao userDao;
    //setter注入需要提供要注入对象的set方法
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    //setter注入需要提供要注入对象的set方法
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }
    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
        userDao.save();
    }
}
  • 在核心配置类applicationContext中配置userDAO的bean,并将其注入到BookService中

  • 执行模拟测试类App2

(从运行结果中可以看到多个引用类型是可以用setter注入的)

  1. 依赖注入 – setter注入普通类型的步骤方法

  1. 在BookDaoImpl中提供两个变量,并提供对应的setter方法(以BookDaoImpl为例)
public class BookDaoImpl implements BookDao {
    private String databaseName;
    private int connectionNum;
    //setter注入需要提供要注入对象的set方法
    public void setConnectionNum(int connectionNum) {
        this.connectionNum = connectionNum;
    }
    //setter注入需要提供要注入对象的set方法
    public void setDatabaseName(String databaseName) {
        this.databaseName = databaseName;
    }
    public void save() {
        System.out.println("book dao save ..."+databaseName+","+connectionNum);
    }
}
  • 在核心配置类applicationContext.xml文件中配置中注入普通变量

  • 模拟测试类App2类的运行结果

相关文章
|
3月前
|
JSON Java Maven
实现Java Spring Boot FCM推送教程
本指南介绍了如何在Spring Boot项目中集成Firebase云消息服务(FCM),包括创建项目、添加依赖、配置服务账户密钥、编写推送服务类以及发送消息等步骤,帮助开发者快速实现推送通知功能。
171 2
|
4月前
|
XML JavaScript Java
Spring Retry 教程
Spring Retry 是 Spring 提供的用于处理方法重试的库,通过 AOP 提供声明式重试机制,不侵入业务逻辑代码。主要步骤包括:添加依赖、启用重试机制、设置重试策略(如异常类型、重试次数、延迟策略等),并可定义重试失败后的回调方法。适用于因瞬时故障导致的操作失败场景。
Spring Retry 教程
|
3月前
|
开发框架 Java API
「SpringBrick快速入门指南」:一款基于Spring Boot的高级插件化开发框架
「SpringBrick快速入门指南」:一款基于Spring Boot的高级插件化开发框架
196 0
|
5月前
|
Java 数据库连接 Spring
一文讲明 Spring 的使用 【全网超详细教程】
这篇文章是一份全面的Spring框架使用教程,涵盖了从基础的项目搭建、IOC和AOP概念的介绍,到Spring的依赖注入、动态代理、事务处理等高级主题,并通过代码示例和配置文件展示了如何在实际项目中应用Spring框架的各种功能。
一文讲明 Spring 的使用 【全网超详细教程】
|
3月前
|
JSON Java Maven
实现Java Spring Boot FCM推送教程
详细介绍实现Java Spring Boot FCM推送教程
129 0
|
6月前
|
NoSQL Java 数据库连接
《滚雪球学Spring Boot》教程导航帖(更新于2024.07.16)
📚 《滚雪球学Spring Boot》是由CSDN博主bug菌创作的全面Spring Boot教程。作者是全栈开发专家,在多个技术社区如CSDN、掘金、InfoQ、51CTO等担任博客专家,并拥有超过20万的全网粉丝。该教程分为入门篇和进阶篇,每篇包含详细的教学步骤,涵盖Spring Boot的基础和高级主题。
103 1
《滚雪球学Spring Boot》教程导航帖(更新于2024.07.16)
|
5月前
|
SQL Java 数据库连接
Spring Boot联手MyBatis,打造开发利器:从入门到精通,实战教程带你飞越编程高峰!
【8月更文挑战第29天】Spring Boot与MyBatis分别是Java快速开发和持久层框架的优秀代表。本文通过整合Spring Boot与MyBatis,展示了如何在项目中添加相关依赖、配置数据源及MyBatis,并通过实战示例介绍了实体类、Mapper接口及Controller的创建过程。通过本文,你将学会如何利用这两款工具提高开发效率,实现数据的增删查改等复杂操作,为实际项目开发提供有力支持。
415 0
|
5月前
|
Java 关系型数据库 MySQL
|
6月前
|
XML Java API
Spring Boot快速入门指南
Spring Boot快速入门指南
|
6月前
|
Java 索引 Spring
教程:Spring Boot中集成Elasticsearch的步骤
教程:Spring Boot中集成Elasticsearch的步骤