Spring IOC之对象的创建方式、策略及销毁时机和生命周期且获取方式

这篇具有很好参考价值的文章主要介绍了Spring IOC之对象的创建方式、策略及销毁时机和生命周期且获取方式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、对象的创建方式

1. 使用构造方法

2. 使用工厂类方法

3. 使用工厂类的静态方法

二、对象的创建策略

1. 单例策略

2. 多例策略

三、对象的销毁时机

四、生命周期方法

1. 定义生命周期方法

2. 配置生命周期方法

3. 测试

五、获取Bean对象的方式

1. 通过id/name获取

2. 通过类型获取

3. 通过类型+id/name获取

往期专栏&文章相关导读 


一、对象的创建方式

Spring会帮助我们创建bean,那么它底层是调用什么方法进行创建的呢?有以下三种方法

  1. 使用构造方法
  2. 使用工厂类方法
  3. 使用工厂类的静态方法

接下来详细讲解这三种方法。

1. 使用构造方法

        Spring默认使用类的空参构造方法创建bean,假如类没有空参构造方法,将无法完成bean的创建,接下来我们可以测试一下。

package com.example.dao;

import com.example.pojo.Student;

public class StudentDaoImpl1 implements StudentDao{

    /*public StudentDaoImpl1() {
    }*/

    public StudentDaoImpl1(int a){};
    @Override
    public Student findById(int id){
        return new Student(id,"程序员","北京");
    }
}

Spring IOC之对象的创建方式、策略及销毁时机和生命周期且获取方式

错误原因:Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'studentDao' defined in class path resource [bean.xml]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'int' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

翻译:上下文初始化过程中遇到异常-取消刷新尝试:org.springframework.beans.factory.UnsatisfiedDependencyException:创建类路径资源[bean.xml]中定义的名称为“studentDao”的bean时出错:通过构造函数参数0表示的不满足依赖关系;嵌套异常为org.springframework.beans.factory.NoSuchBeanDefinitionException:没有可用的类型为“int”的符合条件的bean:应至少有1个符合自动连线候选条件的bean。依赖项注释:{}

其实就是没有空的构造函数,加上一个就好了

2. 使用工厂类方法

        Spring可以调用工厂类的方法创建bean:创建工厂类,工厂类提供创建对象的方法,在配置文件中配置创建bean的方式为工厂方式。

工厂类StudentDaoFactory:

package com.example.dao;

public class StudentDaoFactory {

    public StudentDao getStudentDao(){
        return new StudentDaoImpl1(1);
    }

}

bean.xml的配置:

    <!-- id: 工厂对象的id,class:工厂类 -->
    <bean id="studentDaoFactory" class="com.example.dao.StudentDaoFactory" />
    <!-- id:bean对象的id,factory-bean:工厂对象的id,factory-method:工厂方法 -->
    <bean id="studentDao" factory-bean="studentDaoFactory" factory-method="getStudentDao"></bean>

测试方法: 

    @Test
    public void t2(){
        // 创建spring容器
        ApplicationContext ac = new FileSystemXmlApplicationContext("C:\\JavaProjects\\06SSM_Projects\\springdemo\\spring_ioc1\\src\\main\\resources\\bean.xml");

        // 从容器中获取对象
        StudentDao userDao = ac.getBean("studentDao",StudentDao.class);
        System.out.println(userDao);
        System.out.println(userDao.findById(1));;
    }

测试结果: 

Spring IOC之对象的创建方式、策略及销毁时机和生命周期且获取方式

OK,确实成功写出来了 

3. 使用工厂类的静态方法

        Spring可以调用工厂类的静态方法创建bean,创建工厂类,工厂提供创建对象的静态方法,在配置文件中配置创建bean的方式为工厂静态方法。

工厂类StudentDaoFactory2

package com.example.dao;

public class StudentDaoFactory2 {
    public static StudentDao getStudentDao2() {
        return new StudentDaoImpl2();
    }
}

bean.xml的配置 

    <!-- id:bean的id class:工厂全类名 factory-method:工厂静态方法 -->
     <bean id="studentDao" class="com.example.dao.StudentDaoFactory2" factory-method="getStudentDao2"/>

Spring IOC之对象的创建方式、策略及销毁时机和生命周期且获取方式

都是可以成功运行的。 

二、对象的创建策略

        scope属性设置对象的创建策略。Spring通过配置 <bean> 中的 scope 属性设置对象的创建策略,共有两种种创建策略。

1. 单例策略

        singleton:单例,默认策略。整个项目只会创建一个对象,通过 <bean> 中的 lazy-init 属性可以设置单例对象的创建时机:lazy-init="false"(默认):立即创建,在容器启动时会创建配置文件中的所有Bean对象。lazy-init="true":延迟创建,第一次使用Bean对象时才会创建。下面测试获取对象后的哈希值是否一样就可以知道是否配置单例策略了

bean.xml的配置 

    <bean id="studentDao" class="com.example.dao.StudentDaoImpl2" scope="singleton" lazy-init="true" />

测试方法 

    @Test
    public void t3(){
        // 创建Spring容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        // 从容器获取对象
        StudentDao studentDao1 = ac.getBean("studentDao",StudentDao.class);
        StudentDao studentDao2 = ac.getBean("studentDao",StudentDao.class);
        StudentDao studentDao3 = ac.getBean("studentDao",StudentDao.class);

        System.out.println(studentDao1.hashCode());
        System.out.println(studentDao2.hashCode());
        System.out.println(studentDao3.hashCode());
    }

运行结果 

Spring IOC之对象的创建方式、策略及销毁时机和生命周期且获取方式

        OK,得到的对象都是同一个哈希值,说明确实是同一个对象也就是说成功配置了单例模式。 

2. 多例策略

prototype:多例,每次从容器中获取时都会创建对象。

bean.xml配置 

<!-- 配置多例策略 -->
<bean id="studentDao" class="com.itbaizhan.dao.StudentDaoImpl2" scope="prototype"></bean>

测试结果 

Spring IOC之对象的创建方式、策略及销毁时机和生命周期且获取方式

得到的哈希值不一样,说明得到的是不同的对象,确实是多例策略 。

request:每次请求创建一个对象,只在web环境有效。
session:每次会话创建一个对象,只在web环境有效。
gloabal-session:一次集群环境的会话创建一个对象,只在web环境有效。

三、对象的销毁时机

对象的创建策略不同,销毁时机也不同:

  1. singleton:对象随着容器的销毁而销毁。
  2. prototype:使用JAVA垃圾回收机制销毁对象。
  3. request:当处理请求结束,bean实例将被销毁。
  4. session:当HTTP Session最终被废弃的时候,bean也会被销毁掉。
  5. gloabal-session:集群环境下的session销毁,bean实例也将被销毁。

四、生命周期方法

        Bean对象的生命周期包含创建——使用——销毁,Spring可以配置Bean对象在创建和销毁时自动执行的方法:

1. 定义生命周期方法

在StudentDaoImpl2中新增生命周期方法

    // 创建时自动执行的方法
    public void init(){
        System.out.println("使用StudentDaoImpl2创建对象"+this.hashCode());
    }

    // 销毁时自动执行的方法
    public void destroy(){
        System.out.println("销毁StudentDaoImpl2创建的对象"+this.hashCode());
    }

2. 配置生命周期方法

    <!-- init-method:创建对象时执行的方法 destroy-method:销毁对象时执行的方法 -->
    <bean id="studentDao" class="com.itbaizhan.dao.StudentDaoImpl2" scope="singleton" init-method="init" destroy-method="destory"></bean>

3. 测试

测试方法

@Test
public void t3(){
  // 创建Spring容器
  ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("bean1.xml");
  // 销毁Spring容器,ClassPathXmlApplicationContext才有销毁容器的方法
  ac.close();
}

测试结果 

Spring IOC之对象的创建方式、策略及销毁时机和生命周期且获取方式

也确实可以 

五、获取Bean对象的方式

1. 通过id/name获取

获取对象的时候是这样:

StudentDao studentDao = (StudentDao) ac.getBean("studentDao");

2. 通过类型获取

获取对象的时候是这样:

StudentDao studentDao2 = ac.getBean(StudentDao.class);

不需要进行类型强转

3. 通过类型+id/name获取

        虽然使用类型获取不需要强转,但如果在容器中有一个接口的多个实现类对象,则获取时会报错,此时需要使用类型+id/name获取,获取对象是这样:

StudentDao studentDao2 = ac.getBean("studentDao",StudentDao.class);

往期专栏&文章相关导读 

     大家如果对于本期内容有什么不了解的话也可以去看看往期的内容,下面列出了博主往期精心制作的Maven,Mybatis等专栏系列文章,走过路过不要错过哎!如果对您有所帮助的话就点点赞,收藏一下啪。其中Spring专栏有些正在更,所以无法查看,但是当博主全部更完之后就可以看啦。文章来源地址https://www.toymoban.com/news/detail-427591.html

Maven系列专栏文章
Maven系列专栏 Maven工程开发
Maven聚合开发【实例详解---5555字】
Mybatis系列专栏文章
Mybatis系列专栏 MyBatis入门配置
Mybatis入门案例【超详细】
MyBatis配置文件 —— 相关标签详解
Mybatis模糊查询——三种定义参数方法和聚合查询、主键回填
Mybatis动态SQL查询 --(附实战案例--8888个字--88质量分)
Mybatis分页查询——四种传参方式
Mybatis一级缓存和二级缓存(带测试方法)
Mybatis分解式查询
Mybatis关联查询【附实战案例】
MyBatis注解开发---实现增删查改和动态SQL
MyBatis注解开发---实现自定义映射关系和关联查询
Spring系列专栏文章
Spring系列专栏 Spring IOC 入门简介【自定义容器实例】
IOC使用Spring实现附实例详解
Spring IOC之对象的创建方式、策略及销毁时机和生命周期且获取方式
Spring DI简介及依赖注入方式和依赖注入类型
Spring IOC相关注解运用——上篇
Spring IOC相关注解运用——下篇
Spring AOP简介及相关案例
注解、原生Spring、SchemaBased三种方式实现AOP【附详细案例】
Spring事务简介及相关案例
Spring 事务管理方案和事务管理器及事务控制的API
Spring 事务的相关配置、传播行为、隔离级别及注解配置声明式事务

到了这里,关于Spring IOC之对象的创建方式、策略及销毁时机和生命周期且获取方式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 如何实现Spring中服务关闭时对象销毁执行代码

    1.实现DisposableBean接口的destroy 2.在bean类的方法上增加@PreDestroy方法,那么这个方法会在DisposableBean.destory方法前触发 3.实现SmartLifecycle接口的stop方法 那么这个时候我们去启动一个spring容器 这个时候其实销毁方法是不会执行的,我们可以通过,调用close方法触发或者调用register

    2024年02月01日
    浏览(12)
  • IOC之Spring统一资源加载策略

    IOC之Spring统一资源加载策略

    🎬作者简介:大家好,我是小徐🥇 ☁️博客首页:CSDN主页 小徐的博客 🌄每日一句: 好学而不勤非真好学者 在学 Java的时候,我们学习了一个标准类  java.net.URL ,该类在 Java SE 中的定位为统一资源定位器(Uniform Resource Locator),但是我们知道它的实现基本只限于网络形式

    2024年01月16日
    浏览(8)
  • 【Spring专题】Spring之Bean的生命周期源码解析——阶段二(IOC之实例化)

    【Spring专题】Spring之Bean的生命周期源码解析——阶段二(IOC之实例化)

    由于Spring源码分析是一个前后联系比较强的过程,而且这边分析,也是按照代码顺序讲解的,所以不了解前置知识的情况下,大概率没办法看懂当前的内容。所以,特别推荐看看我前面的文章(自上而下次序): Spring底层核心原理解析——引导篇【学习难度: ★★☆☆☆ 】

    2024年02月13日
    浏览(16)
  • spring的aop动态代理对象注入时机

    spring的aop动态代理对象注入时机

    bean生命周期: bean实例化 populateBean填充属性 invokeAwareMethods调用aware方法 postProcessBeforeInitialization后置处理器before方法 initializeBean初始化bean postProcessAfterAfterInitialization后置处理器after方法 代理对象注入有两种情况:提前和非提前生成代理对象 1. 非提前生成代理对象 依赖于bea

    2024年02月12日
    浏览(11)
  • 【Spring专题】Spring之Bean的生命周期源码解析——阶段二(二)(IOC之属性填充/依赖注入)

    【Spring专题】Spring之Bean的生命周期源码解析——阶段二(二)(IOC之属性填充/依赖注入)

    由于Spring源码分析是一个前后联系比较强的过程,而且这边分析,也是按照代码顺序讲解的,所以不了解前置知识的情况下,大概率没办法看懂当前的内容。所以,特别推荐看看我前面的文章(自上而下次序): Spring底层核心原理解析【学习难度: ★★☆☆☆ 】 手写简易

    2024年02月12日
    浏览(10)
  • SpringApplication对象的构建及spring.factories的加载时机

    构建SpringApplication对象源码: 1、调用启动类的main()方法,该方法中调用SpringApplication的run方法。 2、调用SpringApplication的run()方法的重载方法,在发方法内构建了SpringApplication对象 3、构建SpringApplication对象。 构建过程: 接下来我们来详细研究一下上述过程。在构建SpringApplication对

    2024年02月14日
    浏览(10)
  • Effective第三版 中英 | 第2章 创建和销毁对象 | 用私有构造器或者枚举类型强化 Singleton 属性

    Effective第三版 中英 | 第2章 创建和销毁对象 | 用私有构造器或者枚举类型强化 Singleton 属性

    大家好,这里是 Rocky 编程日记 ,喜欢后端架构及中间件源码,目前正在阅读 effective-java 书籍。同时也把自己学习该书时的笔记,代码分享出来,供大家学习交流,如若笔记中有不对的地方,那一定是当时我的理解还不够,希望你能及时提出。如果对于该笔记存在很多疑惑,

    2024年02月07日
    浏览(11)
  • 【Jetpack】Room 中的销毁重建策略 ( 创建临时数据库表 | 拷贝数据库表数据 | 删除旧表 | 临时数据库表重命名 )

    【Jetpack】Room 中的销毁重建策略 ( 创建临时数据库表 | 拷贝数据库表数据 | 删除旧表 | 临时数据库表重命名 )

    在 Android 中使用 Room 操作 SQLite 数据库 , 如果 SQLite 数据库表 修改比较繁琐 , 如 : 涉及到 修改 数据库表字段的数据类型 , 需要逐个修改数据库值 ; 该环境下 使用 销毁 和 重建策略 是 最佳的方案 ; 销毁 和 重建策略 执行步骤 : 以 Table 表为例 , 要对 Table 表中的数据进行繁琐的

    2024年02月08日
    浏览(11)
  • Effective第三版 中英 | 第2章 创建和销毁对象 | 当面临多个参数的构造器时考虑使用构建器

    Effective第三版 中英 | 第2章 创建和销毁对象 | 当面临多个参数的构造器时考虑使用构建器

    大家好,这里是 Rocky 编程日记 ,喜欢后端架构及中间件源码,目前正在阅读 effective-java 书籍。同时也把自己学习该书时的笔记,代码分享出来,供大家学习交流,如若笔记中有不对的地方,那一定是当时我的理解还不够,希望你能及时提出。如果对于该笔记存在很多疑惑,

    2024年02月07日
    浏览(14)
  • 你知道Unity IoC Container是如何创建对象的吗?

    你知道Unity IoC Container是如何创建对象的吗?

    ty是微软PP推出的一个开源的IoC框架,最新的官方版本是2.0。Unity之前的版本建立在一个称为ObjectBuild的组件上,熟悉EnterLib的读者,相信对ObjectBuild不会感到陌生。对于EnterLib 5.0之前的版本,ObjectBuild可以说是所有Application Block的基石。ObjectBuild提供一种扩展、可定制的对象创建

    2024年02月09日
    浏览(9)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包