当前位置: 首页 > article >正文

spring学习(spring-bean实例化(实现FactoryBean规范)(延迟实例化bean))

目录

一、spring容器实例化bean的几种方式。

(1)无参构造与有参构造方法。

(2)静态工厂与实例工厂。

(3)实现FactoryBean规范。

二、spring容器使用实现FactoryBean规范方式实现bean实例化。

(1)基本介绍。

(2)实现FactoryBean规范完成bean实例化的基本步骤。

1、测试项目准备工作。

2、指定工厂类中实现FactoryBean接口。

<1>方法getObject()。

<2>方法getObjectType()。

<3>方法isSingleton()。

3、spring配置文件中配置bean。(交给spring容器管理)

4、测试类。(MainApp)

(3)debug模式查看FactoryBean规范方式是延迟实例化bean。

1、设置断点。执行debug模式。

2、推进程序的执行,查看重要变量的赋值。

<1>属性beanFactory、beanDefinitionMap。

<2>属性singletonObjects。

<3>spring缓存机制。属性factoryBeanObjectCache。


  • 本篇博客接着上篇《spring容器使用实例工厂实例化bean》继续学习。

一、spring容器实例化bean的几种方式。

(1)无参构造与有参构造方法。
  • 使用构造方法实例化bean。spring学习(spring-bean实例化(无参构造与有参构造方法实现)详解)-CSDN博客

(2)静态工厂与实例工厂。
  • 使用静态工厂方式实例化bean。spring学习(spring-bean实例化(静态工厂))-CSDN博客
  • 使用实例工厂方式实例化bean。spring学习(spring-bean实例化(实例工厂))-CSDN博客

(3)实现FactoryBean规范。
  • 最后一种实例化bean的方式:实现FactoryBean规范。(在本篇博客进行学习)

二、spring容器使用实现FactoryBean规范方式实现bean实例化。

  • 实现FactoryBean规范涉及实现接口FactoryBean<泛型>
(1)基本介绍。
  • 在spring框架中,FactoryBean是一种特殊的bean,允许我们进行自定义实例化bean的过程
  • 通过实现FactoryBean<?>接口,可以控制spring容器完成创建和初始化bean。

(2)实现FactoryBean规范完成bean实例化的基本步骤。
1、测试项目准备工作。
  • 本篇博客通过简单demo工程进行代码演示。
  • 整体的项目结构。分为工厂包(factory)、业务层包(service)、测试包(test)。
  • 目的:类"UserServiceFactoryBean"实现FactoryBean规范并为类"UserServiceImpl"实例化bean。


2、指定工厂类中实现FactoryBean<?>接口。
  • 注:"<?>"表示需提供的泛型。(表示需要实例化bean的类型)
  • 具体核心操作是实现该接口的两个方法。另外一个方法一般不实现。下面具体介绍!

<1>方法getObject()。
  • 代替实例工厂提供的实例方法或者静态工厂提供的静态方法。
  • 作用:返回<?>泛型指定类型的实例化bean

<2>方法getObjectType()。
  • 作用:返回创建的实例的类型(返回对应的字节码对象:xxx.class)

<3>方法isSingleton()。
  • 方法isSingleton()。作用:设置spring容器实例化的bean是单例还是非单例对象

  • 它是FactoryBean接口中的default方法。不强制要求实现类去实现。
  • 在Java中default类型的方法是一种特殊的方法,它允许接口中包含具体的实现代码,这样实现该接口的类可以继承这些方法的实现,但也可以覆盖它们以提供自己的实现。

  • 类"UserServiceFactoryBean"(实现FactoryBean的工厂)。

package com.fs.factory;

import com.fs.service.UserService;
import com.fs.service.impl.UserServiceImpl;
import org.springframework.beans.factory.FactoryBean;

//实现FactoryBean的UserService工厂
public class UserServiceFactoryBean implements FactoryBean<UserServiceImpl> {

    //代替原始实例工厂创建对象的实例方法
    @Override
    public UserServiceImpl getObject() throws Exception {
        System.out.println("UserServiceFactoryBean已工作......");
        //return——UserServiceImpl对象
        return new UserServiceImpl();
    }

    //返回创建的实例的类型(返回对应类型的字节码.class)
    @Override
    public Class<?> getObjectType() {
        return UserService.class;
    }

    //设置实例化的bean是否单例
    @Override
    public boolean isSingleton() {
        return true;
        //若不想返回单例的bean就return false
        //return false;
    }
}
3、spring配置文件中配置bean。(交给spring容器管理)
  • 不像静态工厂或者实例工厂实例化bean时,需要在<bean>标签上使用属性"factory_bean"或"factory_method"指定工厂或者指定方法(静态/实例)。

  • 实现FactoryBean规范在spring配置文件的操作比较简单。
  • 只需要将实现FactoryBean<?>接口的类完成<bean>标签的基础配置即可(id与class)。
<?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">
    <!--实现FactoryBean规范实例化bean-->
    <!--配置UserServiceFactoryBean——生产UserServiceImpl类的bean-->
    <bean id="userServiceFactoryBean" class="com.fs.factory.UserServiceFactoryBean"></bean>
</beans>
4、测试类。(MainApp)
  • 使用ApplicationContext容器加载配置文件,并通过容器对象getBean()指定实现FactoryBean接口的工厂类的id获取对应实例化(UserServiceImpl类)的bean。
package com.fs.test;

import com.fs.service.impl.UserServiceImpl;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
    public static void main(String[] args) {
        //使用IoC容器(ApplicationContext)获取spring容器管理的bean对象
        //1.创建容器对象。实例化时参数指定对应的配置文件
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("springBean.xml");
        //2.通过<bean>标签的唯一标识id获取对应在spring容器已经配置的bean对象(生产UserServiceImpl类的bean)
        Object obj = context.getBean("userServiceFactoryBean");
        //3.强制类型转换
        UserServiceImpl userService = (UserServiceImpl) obj;
        //4.调用UserService中的save方法
        userService.save();
    }
}
  • 程序测试运行结果。


(3)debug模式查看FactoryBean规范方式是延迟实例化bean。
1、设置断点。执行debug模式。
  • 在测试类中设置合适的断点。查看程序运行的整个过程。


2、推进程序的执行,查看重要变量的赋值。
  • 刚进入main()方法。


  • 执行第1步。
<1>属性beanFactory、beanDefinitionMap。


<2>属性singletonObjects。
  • 发现"userServiceFactoryBean"与存储在beanDefinitionMap中的地址不一样。
  • 因为底层spring实例化bean时,解析完<bean>标签后存储在beanDefinitionMap里面的bean再以键名的方式遍历存储到singletonObjects中。
  • 此时还是没有发现工厂帮我们返回的"UserServiceImpl"的bean。(延迟实例化bean



<3>spring缓存机制。属性factoryBeanObjectCache。
  • 此时还在第一步。
  • 当getBean()方法未执行。说明ApplicationContext容器创建后,我们需要的实例化bean(UserServiceImpl)还未及时创建(延时实例bean)。


  • 继续下一步。执行getBean()方法后。


  • 此时缓存变量"factoryBeanObjectCache"已经有对应已经实例好的bean了。


http://www.kler.cn/a/442525.html

相关文章:

  • 升级 SpringBoot3 全项目讲解 — 为什么 SpringBoot3 应该抛弃 Maven,搭配 Gradle 来使用?
  • [手机Linux] ubuntu 错误解决
  • Android中下载 HAXM 报错 HAXM installation failed,如何解决?
  • 近红外简单ROI分析matlab(NIRS_SPM)
  • Android JecPack组件之LifeCycles 使用详解
  • C语言 - 可变参数函数 va_list、va_start、va_arg、va_end
  • java error(2)保存时间带时分秒,回显时分秒变成00:00:00
  • shared_ptr 智能指针
  • HDFS常用命令
  • IIS服务器部署C# WebApi程序,客户端PUT,DELETE请求无法执行
  • vue3 + ts + element-plus 表格中的input按回车聚焦到下一行
  • 电商大数据的几种获取渠道分享!
  • 数据可视化-4. 漏斗图
  • 国内主流数据库介绍及技术分享
  • vue iframe进行父子页面通信并切换URL
  • 基于Streamlit和OpenAI大模型的Chatbot App支持图片的多模态输入
  • 使用 Copilot 增强创造力:Mighty Media 的卓越数字化之旅
  • 【论文复刻】2021-2012年环境规制影响企业融资约束吗—基于新《环保法》的准自然实验(C刊《证券市场导报》)
  • RPA 在促销活动自动化处理中的创新应用
  • CSS3:重塑网页设计的新力量
  • YOLO目标检测算法
  • 【DevOps工具篇】Gitlab Runner设置(使用Docker in docker作为Runner)
  • LAPACK 程序 SSYEVD 的计算特征值的应用实例 C/Fortran
  • 数据结构 ——哈希表
  • React工具和库面试题目(二)
  • 2024.12.15 TCP/IP 网络模型有哪几层?(二)