BeanFactory容器的构建和使用示例

news2024/11/26 14:53:19

BeanFactory容器的实现流程:

BeanFactory是Spring框架中的一部分,它提供了IoC(控制反转)的实现机制。下面是BeanFactory的IoC实现过程:

  1. 定义Bean定义:首先,我们需要在配置文件中定义Bean的定义。Bean的定义包括Bean的名称、类型以及其他属性。这些定义可以使用XML、注解或其他方式进行配置。
public interface UserService {
    void sayHello();
}

  1. 加载配置文件:BeanFactory会负责加载配置文件,并解析其中的Bean定义。这可以通过不同的方式实现,如XML配置文件、注解扫描等。例如,在XML配置中,可以使用ClassPathXmlApplicationContext来加载和解析XML配置文件。

  2. 创建Bean实例:当配置文件被加载和解析后,BeanFactory会根据定义的信息实例化Bean对象。BeanFactory使用反射机制根据Bean的类名创建一个新的实例。可以选择不同的容器实现类,如DefaultListableBeanFactory。

import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionReader;
import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader;
import org.springframework.core.io.ClassPathResource;

public class MyApp {
    public static void main(String[] args) {
        // 创建DefaultListableBeanFactory容器实例
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

        // 创建Bean定义注册表
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;

        // 创建Bean定义读取器
        BeanDefinitionReader reader = new PropertiesBeanDefinitionReader(registry);

        // 加载Bean定义配置文件
        reader.loadBeanDefinitions(new ClassPathResource("mybeans.properties"));

        // 获取并初始化BeanFactory容器中的所有bean对象
        beanFactory.preInstantiateSingletons();

        // 获取所需的Bean
        MyBean myBean = beanFactory.getBean(MyBean.class);

        // 使用Bean
        myBean.doSomething();
    }
}

  1. 依赖注入:在Bean实例化完成后,BeanFactory会处理Bean之间的依赖关系。它会检查Bean中的依赖项,并将依赖项注入到对应的属性中。这个过程称为依赖注入(Dependency Injection)。
public class OrderService {
    private UserService userService;

    public void setUserService(UserService userService) {
        this.userService = userService;
    }
}

public class Main {
    public static void main(String[] args) {
        // 创建BeanFactory容器并加载XML配置文件
        BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("application-context.xml"));

        // 创建userService和orderService实例
        UserService userService = (UserService) beanFactory.getBean("userService");
        OrderService orderService = new OrderService();

        // 手动进行依赖注入
        orderService.setUserService(userService);
    }
}

其中,调用 getBean 的时候,从 BeanDefinition 所属的 Map 里,拿出 Class 对象进行实例化,同时,如果有依赖关系,将递归调用 getBean 方法 —— 完成依赖注入。
getBean的流程如下所示:
在这里插入图片描述

  1. 管理Bean的生命周期:BeanFactory还负责管理Bean的整个生命周期。它会调用Bean的初始化方法进行必要的初始化操作,并在容器关闭时调用销毁方法释放资源。
public class UserService implements InitializingBean, DisposableBean {
    // 初始化方法
    public void afterPropertiesSet() throws Exception {
        System.out.println("UserService 初始化");
    }

    // 销毁方法
    public void destroy() throws Exception {
        System.out.println("UserService 销毁");
    }
}

public class Main {
    public static void main(String[] args) {
        // 创建BeanFactory容器并加载XML配置文件
        BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("application-context.xml"));

        // 创建userService实例
        UserService userService = (UserService) beanFactory.getBean("userService");

        // 手动触发销毁方法
        ((DisposableBean) userService).destroy();
    }
}

  1. 提供Bean的访问:一旦Bean的实例化和依赖注入完成,BeanFactory可以通过名称或类型提供对Bean的访问。开发人员可以使用Bean的名称或类型从BeanFactory中获取相应的实例。
public class Main {
    public static void main(String[] args) {
        // 创建BeanFactory容器并加载XML配置文件
        BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("application-context.xml"));

        // 通过名称获取userService实例
        UserService userService1 = (UserService) beanFactory.getBean("userService");

        // 通过类型获取userService实例
        UserService userService2 = beanFactory.getBean(UserService.class);
    }
}

以上这种方式将控制权从开发人员转移到了容器中,容器负责管理对象的创建和维护依赖关系。这样可以降低代码的耦合度,并提供更灵活和可扩展的应用程序架构。

如何实现和使用BeanFactory容器

当使用Spring框架时,我们可以通过配置文件或注解来实现和使用BeanFactory容器。下面我将分别给出两个详细的例子。

1. 使用XML配置文件实现BeanFactory容器:

首先,创建一个名为applicationContext.xml的XML配置文件,其中定义了我们需要管理的Bean及其依赖关系。假设我们要创建一个简单的用户服务类(UserService)和一个依赖于用户服务的订单服务类(OrderService)。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">

    <!-- 定义UserService -->
    <bean id="userService" class="com.example.UserService" />

    <!-- 定义OrderService,并注入UserService依赖 -->
    <bean id="orderService" class="com.example.OrderService">
        <property name="userService" ref="userService" />
    </bean>

</beans>

然后,我们可以编写Java代码来加载和使用这个XML配置文件中定义的Bean。

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

public class Main {
    public static void main(String[] args) {
        // 创建BeanFactory容器并加载XML配置文件
        BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));

        // 从容器中获取Bean实例
        UserService userService = (UserService) beanFactory.getBean("userService");
        OrderService orderService = (OrderService) beanFactory.getBean("orderService");

        // 使用Bean
        userService.sayHello();
        orderService.placeOrder();
    }
}

在上述示例中,我们首先创建了一个XmlBeanFactory容器,并通过ClassPathResource指定了XML配置文件的路径。然后,我们使用getBean方法从容器中获取了UserServiceOrderService实例,并调用了它们的方法。

2. 使用注解实现BeanFactory容器:

下面我们演示如何使用注解来实现BeanFactory容器。假设我们有一个名为User的类,并希望将它注册到容器中,并使用Autowired注解来依赖注入。

public class User {
    private String name;

    public User() {}

    public User(String name) {
        this.name = name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void sayHello() {
        System.out.println("Hello, " + name + "!");
    }
}

然后,我们可以编写Java代码来实例化BeanFactory容器并使用注解。

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {
    public static void main(String[] args) {
        // 创建BeanFactory容器并扫描包
        BeanFactory beanFactory = new AnnotationConfigApplicationContext("com.example");

        // 从容器中获取Bean实例
        User user = beanFactory.getBean(User.class);

        // 使用Bean
        user.sayHello();
    }
}

在上面的示例中,我们创建了一个AnnotationConfigApplicationContext容器,并通过传递包名来扫描该包下的注解。然后,我们使用getBean方法从容器中获取了User实例,并调用了它的方法。

这就是使用Spring框架和注解实现BeanFactory容器的一个示例。通过配置文件或注解方式,借助Spring框架的支持,我们可以更加方便地管理和使用Bean对象。

注意:

  1. 确保在项目中引入了正确的Spring框架依赖。
  2. 在使用注解配置时,确保注解所在的包路径是正确的,并且被扫描到了。
  3. 如果使用XML配置文件方式,确保XML配置文件的路径正确,并且文件名为applicationContext.xml。
  4. 在使用依赖注入时,确保被注入的Bean对象存在,并且名称或类型与注入的地方匹配。
  5. 如果有其他的类和方法,确保它们在代码中被正确引用和调用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/778427.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[数据结构]顺序表和ArrayList

顺序表的介绍 在了解顺序表之前先了解一下什么叫做线性表&#xff1a; 线性表&#xff08;linear list&#xff09;&#xff1a;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构。 常见的线性表&#xff1a;顺序表、链表、栈、队列… 线性…

数学建模入门-如何从0开始,掌握数学建模的基本技能

一、前言 本文主要面向没有了解过数学建模的同学&#xff0c;帮助同学们如何快速地进行数学建模的入门并且尽快地在各类赛事中获奖&#xff0c;或者写出优秀的数学建模论文。 在本文中&#xff0c;我将从什么是数学建模、数学建模的应用领域、数学建模的基本步骤、数学建模的技…

两天学会用Webpack打包前端代码-day01

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 什么是 Webpack&#xff1f; 使用 Webpack 体验webpack打包过程 修改 Webpack 打包入口和出口 入口 出…

[JAVAee]线程安全

目录 线程安全的理解 线程不安全的原因 ①非原子性 ②可见性 ③代码重排序 体会何为不安全的线程 保证线程安全 一个代码在多线程的环境下就很容易出现错误. 线程安全的理解 线程安全是什么呢?通俗的来讲,线程安全就是在多线程的环境下,代码的结果是符合我们预期的,就…

R语言-数据分析及建模(第1节)分类与预测问题简介

小伙伴们&#xff0c;今天我们学习R语言-数据分析及建模&#xff08;第1节&#xff09;分类与预测问题简介 01-分类与预测问题简介 ◆分类和预测是预测问题的两种主要类型&#xff0c;分类主要是预测分类标号&#xff08;离散属性&#xff09; &#xff0c;而预测主要是建立连续…

Windows11的VS201x编译OpenCV+Contrib+CUDA

(1) CUDA下载&#xff0c;注意要和cudnn版本号相关。 我安装的是cuda11.0,注意VS2015不能编译CUDA11&#xff0c;所以用VS2015的话需要下载CUDA 10。因为更高的版本目前还没有cudnn。 (2) 下载和安装VS2015。 (3) 下载和解压CMake。 CMake地址&#xff1a; Releases Kitw…

性能测试Ⅱ(压力测试与负载测试详解)

协议 性能理论&#xff1a;并发编程 &#xff0c;系统调度&#xff0c;调度算法 监控 压力测试与负载测试的区别是什么&#xff1f; 负载测试 在被测系统上持续不断的增加压力&#xff0c;直到性能指标(响应时间等)超过预定指标或者某种资源(CPU&内存)使用已达到饱和状…

每天五分钟机器学习:多项式非线性回归模型

本文重点 在前面的课程中,我们学习了线性回归模型和非线性回归模型的区别和联系。多项式非线性回归模型是一种用于拟合非线性数据的回归模型。与线性回归模型不同,多项式非线性回归模型可以通过增加多项式的次数来适应更复杂的数据模式。在本文中,我们将介绍多项式非线性回…

[SpringMVC]仿写SpringMVC(注解开发)

文章目录 前提&#xff1a;1、代码结构2、核心&#xff1a;YhzMVC3、初始化步骤是&#xff1a;4、执行 前提&#xff1a; 当前版本无接受网络请求功能&#xff0c;不喜勿喷&#x1f64f;&#x1f64f; 本文将对代码核心进行讲解&#xff0c;源码已上传到gitee仓库 1、代码结构…

SpringBoot集成Druid实现数据库连接池

一、引入依赖 完整的pom文件如下所示: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http…

第四讲:MySQL中DDL一些基本数据类型及表的创建、查询

目录 1、创建表:2、DDL一些基本数据类型&#xff1a; 1、创建表: 部分单词及解析&#xff1a; 1、tables:表 2、comment:评论&#xff0c;解释 3、gender:性别 4、neighbor&#xff1a;邻居 1、创建表&#xff1a;&#xff08;注&#xff1a;在自定义数据库操作&#xff0c;…

Vue--》打造个性化医疗服务的医院预约系统(二)

今天开始使用 vue3 + ts 搭建一个医院预约系统的前台页面,因为文章会将项目的每一个地方代码的书写都会讲解到,所以本项目会分成好几篇文章进行讲解,我会在最后一篇文章中会将项目代码开源到我的GithHub上,大家可以自行去进行下载运行,希望本文章对有帮助的朋友们能多多关…

分布式锁:Redis、Zookeeper

1.基于Redis实现分布式锁&#xfeff; Redis分布式锁原理如上图所示&#xff0c;当有多个Set命令发送到Redis时&#xff0c;Redis会串行处理&#xff0c;最终只有一个Set命令执行成功&#xff0c;从而只有一个线程加锁成功 2.SetNx命令加锁 利用Redis的setNx命令在Redis数据库…

01 openEuler操作系统介绍

文章目录 01 openEuler操作系统介绍1.1 发布件1.2 最小硬件要求1.3 硬件兼容性1.4 关键特性1.4.1 openEuler 22.03-LTS基于 Linux Kernel 5.10 内核构建, 在进程调度、内存管理等方面带来10余处创新1.4.2 新介质文件系统1.4.3 内存分级扩展1.4.4 用户态协议栈1.4.5 云原生调度增…

【人工智能】深度优先搜索、代价一致搜索、深度有限搜索、迭代深度优先搜索、图搜索

【人工智能】无信息搜索—BFS 、代价一致、DFS、深度受限、迭代深入深度优先、图搜索 什么是搜索 搜索问题是指既不能通过数学建模解决,又没有其他算法可以套用或者非遍历所有情况才能得出正确结果。这时就需要采用搜索算法来解决问题。搜索就是一种通过穷举所有解的状态,来…

【车载开发系列】AUTOSAR DemDTCAttributes

【车载开发系列】AUTOSAR DemDTCAttributes 【车载开发系列】AUTOSAR DemDTCAttributes 【车载开发系列】AUTOSAR DemDTCAttributes一. DemDTCAttributes概念二. DemAgingCycleCounterThreshold三. DemAgingAllowed四. DemDTCPriority五. DemImmediateNvStorage六. DemMaxNumbe…

BatchNorm, LayerNorm, InstanceNorm和GroupNorm

1. 介绍 Batch Norm: 对NHW计算归一化参数(均值和方差)&#xff0c;总共得到C组归一化参数, 相当于对每个channel进行归一化。BN主要缺点是对batchsize的大小比较敏感&#xff0c;由于每次计算均值和方差是在一个batch上&#xff0c;所以如果batchsize太小&#xff0c;则计算的…

idea2021.安装pojie教程

1、下载ideaIU-2021.3应用包&#xff0c;点击finish 2、先关闭idea窗口&#xff0c;等会激活了脚本再运行打开。 3、双击运行install-current-user.vbs&#xff0c;等待一会会提示运行成功。 4、运行后&#xff0c;在文件中会多出一条配置 5、打开运行idea,输入激活码&#x…

iPhone 开机停留在苹果logo画面(已解决)

一、问题 如下图&#xff0c;开不了机&#xff1a; 标题 二、根因 存储空间满了。 三、解决方法 方法一 用苹果数据线&#xff08;最好是原装&#xff09;连接Mac电脑&#xff0c;在装有 macOS Catalina 10.15 或更高版本的 Mac 上&#xff0c;打开“访达”。在装有 macOS…

Vue-组件高级(上)

一、目标 能够掌握watch侦听器的基本使用能够知道vue中常用的生命周期函数能够知道如何实现组件之间的数据共享能够知道如何在vue3.x的项目中全局配置axios 二、目录 watch侦听器 1.什么是watch侦听器 watch侦听器允许开发之监视数据的变化&#xff0c;从而针对数据的变化做…