Spring-ApplictionContext

news2024/11/17 11:55:33

Spring

Spring是整个Java体系最核心的框架,没有之一。

核心类图结构

在这里插入图片描述

ApplicationContext

  • ApplicationEventPublisher:提供了一种机制,用于通知应用程序中感兴趣的部分有关其执行过程中发生的特定事件。
  • ListableBeanFactory:是Spring框架中的一个接口,它继承了BeanFactory接口,是一个具有列表查询能力的Bean工厂。
  • HierarchicalBeanFactory:是Spring框架中的另一个接口,它扩展了BeanFactory接口。
  • ResourcePatternResolver:是 Spring Framework 中的一个接口,用于以资源位置模式的格式解析资源。
  • MessageSource:处理国际化资源的组件,用于支持国际化(i18n)和本地胡(l1On)。
  • EnvironmentCapable:是 Spring Framework 中的一个接口,用于表示一个对象是否具备获取环境(Environment)的能力。
  • FunctionalInterface:是 Java 8 引入的一个新的接口类型,它是一个特殊的接口,只能有一个抽象方法(可以有默认方法和静态方法),用于支持函数式编程。
  • BeanFactory:是 Spring 框架的核心接口之一,主要负责对Bean的配置和管理功能,具体的创建功能是由子类来实现注入的。
  • ResourceLoader:Spring Framework 中的一个接口,用于加载资源(Resource)的抽象。

BeanFactory

它是 Spring IoC(Inversion of Control,控制反转)容器的基础。IoC 容器负责管理和组装应用程序中的对象(也称为 Bean)。
在 Spring 中,BeanFactory 提供了以下主要功能:

  • 实例化对象:BeanFactory 负责根据配置元数据(通常是 XML 或注解)来实例化 Java 对象,这些对象被称为 Beans。它将对象的创建和初始化过程与应用程序代码解耦,使得对象的创建更加灵活和可配置。

  • Bean 的配置管理:BeanFactory 负责管理 Bean 的配置元数据。这些元数据定义了 Bean 的类型、依赖关系和其他属性。配置元数据可以通过 XML 配置文件、Java 注解或 Java 代码进行指定。

  • 依赖注入(Dependency Injection):BeanFactory 通过依赖注入的方式自动解析和设置 Bean 之间的依赖关系。依赖注入消除了硬编码的依赖关系,使得组件之间的协作更加灵活和可维护。

  • 单例和原型模式管理:BeanFactory 可以管理单例(Singleton)和原型(Prototype)两种类型的 Bean。单例 Bean 在容器中只有一个实例,而原型 Bean 每次被请求时都会创建一个新的实例。

  • 生命周期管理:BeanFactory 负责管理 Bean 的生命周期,它在需要的时候创建 Bean、初始化 Bean、调用 Bean 的初始化回调方法,并在容器关闭时销毁 Bean。

BeanFactory 接口定义了一些常用的方法,允许应用程序通过 Bean 名称或类型来访问和管理这些 Bean。常见的实现类包括 DefaultListableBeanFactory 和 XmlBeanFactory。

  • DefaultListableBeanFactory 是 Spring 框架默认的 BeanFactory 实现,支持基于 XML 配置和注解的 Bean 定义( class,scope, 初始化、销毁等信息)。

  • XmlBeanFactory 是较早的实现,它从 XML 配置文件中读取 Bean 定义并实例化相应的 Bean。不过在较新版本的 Spring 中,推荐使用DefaultListableBeanFactory 或者更高级的容器,如 ApplicationContext。

MessageSource

它提供了一种机制,允许应用程序通过统一的接口访问不同语言环境下的文本消息,从而使应用程序可以根据用户的语言偏好显示相应的文本信息。

在国际化和本地化的场景中,不同地区和语言可能有不同的语言、日期格式、货币符号等。通过使用 MessageSource,开发者可以将这些本地化的文本消息抽象出来,而不必硬编码到应用程序代码中,从而方便地实现多语言支持。
主要定义下面方法:

String getMessage(String code, Object[] args, String defaultMessage, Locale locale);
String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException;
String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;

其中,code 是消息的唯一标识符,args 是替换消息中占位符的参数数组,defaultMessage 是在找不到指定消息时的默认文本。locale 参数用于指定所需的语言环境。

Spring 中的 MessageSource 通常由 ResourceBundleMessageSourceReloadableResourceBundleMessageSource 等实现类来支持,这些实现类可以从属性文件(通常是 .properties 文件)或者其他资源中加载本地化消息。

简单的示例:

  1. 在属性文件中定义不同语言环境的消息(例如 messages_en.properties 和 messages_fr.properties):
  • messages_en.properties:
    greeting=Hello!
    
  • messages_fr.properties:
    greeting=Bonjour!
    
  1. 创建一个 Spring Bean,并注入 MessageSource:
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.MessageSource;
    import org.springframework.stereotype.Component;
    
    import java.util.Locale;
    
    @Component
    public class GreetingService {
    
        private final MessageSource messageSource;
    
        @Autowired
        public GreetingService(MessageSource messageSource) {
            this.messageSource = messageSource;
        }
    
        public void printGreeting(Locale locale) {
            String greeting = messageSource.getMessage("greeting", null, "Default Greeting", locale);
            System.out.println(greeting);
        }
    }
    
  2. 在应用程序中使用 GreetingService:
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    import java.util.Locale;
    
    public class MainApp {
    
        public static void main(String[] args) {
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
            GreetingService greetingService = context.getBean(GreetingService.class);
    
            greetingService.printGreeting(Locale.US); // Output: Hello!
            greetingService.printGreeting(Locale.FRENCH); // Output: Bonjour!
    
            context.close();
        }
    }
    
    在上面的示例中,GreetingService 中的 printGreeting 方法会根据传入的 locale 参数获取对应的消息。如果指定的消息未找到,将会返回默认的消息(“Default Greeting”)。

总结
通过 MessageSource,我们可以轻松实现多语言支持,使得应用程序可以根据不同用户的语言偏好提供合适的本地化文本信息。

ResourcePatternResolver

它是 Spring 核心框架的一部分,提供了一种方便的方式来定位资源,例如文件、类路径资源、URL 等,基于给定的模式。
Spring Framework 提供了多种 ResourcePatternResolver 接口的实现,以支持不同的资源定位策略。其中一些常用的实现包括:

  • PathMatchingResourcePatternResolver:这是在 Spring 应用程序中最常用的实现。它可以使用 Ant 风格的路径匹配模式来解析资源,例如 classpath*:com/example/**/*.xml,用于查找 com/example/ 包及其子包中的所有 XML 文件。

  • ServletContextResourcePatternResolver:此实现特定于 Web 应用程序,并允许您相对于 ServletContext 来解析资源。

  • FileSystemResourcePatternResolver:此解析器允许您使用文件系统路径来解析资源,在需要处理类路径之外的资源时很有用。

ResourcePatternResolver 接口提供了几种资源解析的方法,例如 getResources(String locationPattern) 可以获取与指定模式匹配的资源列表,getResource(String location) 可以根据位置获取单个资源等。

Spring 应用程序中使用 ResourcePatternResolver 的示例:

import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import java.io.IOException;

public class ResourceResolverExample {

    public static void main(String[] args) {
        // 创建资源解析器
        PathMatchingResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();

        try {
            // 使用 Ant 风格的模式解析资源
            Resource[] resources = resourceResolver.getResources("classpath*:com/example/**/*.xml");

            // 处理资源
            for (Resource resource : resources) {
                System.out.println("资源:" + resource.getFilename());
                // 在此处处理资源
            }
        } catch (IOException e) {
            // 处理异常
            e.printStackTrace();
        }
    }
}

ApplicationEventPublisher

它是 Spring 的事件驱动编程模型的一部分,可以在Sring应用程序中发布一些事件,对于订阅该特定类型的事件的的相关组件都可以订阅这些事件。允许 Spring 应用程序内的组件以松散耦合的方式进行通信和交互,通过事件来实现。

  1. 创建一个事件类
// 创建一个事件类
import org.springframework.context.ApplicationEvent;

public class CustomEvent extends ApplicationEvent {
    public CustomEvent(Object source) {
        super(source);
    }

    // 根据需要添加自定义属性和方法。
}
  1. 创建一个事件发布者
// 创建一个事件发布者
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;

public class CustomEventPublisher implements ApplicationEventPublisherAware {

    private ApplicationEventPublisher eventPublisher;

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) {
        this.eventPublisher = eventPublisher;
    }

    public void doSomethingAndPublishEvent() {
        // 做一些重要的事情...
        
        // 创建并发布事件
        CustomEvent customEvent = new CustomEvent(this);
        eventPublisher.publishEvent(customEvent);
    }
}
  1. 创建一个事件监听器
// 创建一个事件监听器:
import org.springframework.context.ApplicationListener;

public class CustomEventListener implements ApplicationListener<CustomEvent> {

    @Override
    public void onApplicationEvent(CustomEvent event) {
        // 在这里处理自定义事件
        // 当事件被发布时,该方法将被调用。
    }
}

  1. 将监听器和发布器注入到容器中
<bean id="customEventPublisher" class="com.example.CustomEventPublisher" />
<bean id="customEventListener" class="com.example.CustomEventListener" />

ListableBeanFactory

ListableBeanFactory还提供了一些用于查询和获取Bean的扩展方法,使得可以方便地获取容器中的所有Bean或按条件进行Bean的查找。

主要的方法包括:

  • getBeanDefinitionCount(): 返回容器中注册的Bean定义的数量。

  • getBeanDefinitionNames(): 返回容器中所有注册的Bean的名称列表。

  • getBeanNamesForType(Class<?> type): 根据给定的类型返回对应的Bean名称列表。

  • getBeansOfType(Class type): 返回容器中给定类型的Bean实例的映射,其中Key为Bean名称,Value为对应的Bean实例。

这些方法使得开发人员可以很方便地根据类型或名称来获取容器中的Bean,而不需要手动遍历整个Bean定义列表。

示例:

假设我们有以下的两个Bean类,使用注解的示例:

@Component
public class User {
    // ...
}

@Component
public class Product {
    // ...
}

然后,我们可以通过ListableBeanFactory来获取容器中的所有Bean或按类型获取Bean:

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

public class MainApp {
    public static void main(String[] args) {
        ListableBeanFactory context = new AnnotationConfigApplicationContext(MainApp.class);
        
        // 获取容器中所有Bean的名称
        String[] beanNames = context.getBeanDefinitionNames();
        for (String beanName : beanNames) {
            System.out.println("Bean Name: " + beanName);
        }
        
        // 按类型获取Bean
        Map<String, User> users = context.getBeansOfType(User.class);
        for (Map.Entry<String, User> entry : users.entrySet()) {
            System.out.println("User Bean Name: " + entry.getKey());
        }
    }
}

HierarchicalBeanFactory

HierarchicalBeanFactory定义了一种层次结构,可以用于组织和管理多个BeanFactory实例,从而构建更复杂的容器结构。
在Spring中,HierarchicalBeanFactory接口主要用于以下两种场景:

  • 层次性的Bean查找:如果有多个BeanFactory层次相嵌套,可以通过层次性的Bean查找来从一个容器中查找Bean,如果找不到,则会递归地向上级容器查找,直到找到或者到达根容器。
  • 属性覆盖:层次性的BeanFactory允许子容器覆盖父容器中的Bean定义。在子容器中可以定义一个与父容器相同ID的Bean定义,从而覆盖父容器中的对应Bean。

通常情况下,ApplicationContext接口实现了HierarchicalBeanFactory接口,因此,ApplicationContext可以利用HierarchicalBeanFactory提供的功能。
如何使用层次性的BeanFactory:

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

public class MainApp {
    public static void main(String[] args) {
        // 创建父容器,并加载配置文件beans-parent.xml
        HierarchicalBeanFactory parentBeanFactory = new XmlBeanFactory(new ClassPathResource("beans-parent.xml"));
        
        // 创建子容器,并加载配置文件beans-child.xml
        XmlBeanFactory childBeanFactory = new XmlBeanFactory(new ClassPathResource("beans-child.xml"), parentBeanFactory);
        
        // 在子容器中获取名为"user"的Bean
        User user = (User) childBeanFactory.getBean("user");
        
        // 调用User的方法
        user.greet();
    }
}

EnvironmentCapable

是一个表示应用程序当前运行环境的接口。它可以用于获取配置属性、激活的配置文件、配置文件的属性值等。Spring 应用程序可以有多个不同的环境,例如开发、测试、生产环境等,并且根据不同环境进行配置和运行。
EnvironmentCapable 接口定义了一个方法:

Environment getEnvironment();

实现该接口的类需要提供这个方法的具体实现,以返回一个 Environment 实例。通过实现此接口,对象可以获取与应用程序配置相关的环境信息,并相应地调整其行为。
示例:

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.env.Environment;

public class EnvironmentExample {

    public static void main(String[] args) {
        // 创建并初始化 Spring 应用程序上下文
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

        // 获取环境信息
        Environment environment = context.getEnvironment();

        // 获取配置属性值
        String propertyValue = environment.getProperty("app.name");
        System.out.println("应用程序名称:" + propertyValue);
    }
}

ResourceLoader

它是 Spring 的资源加载机制的核心接口,提供了一种统一的方式来获取不同类型的资源,如文件、类路径资源、URL 等。
ResourceLoader 接口定义了一个方法:

Resource getResource(String location);

实现该接口的类需要提供这个方法的具体实现,以根据给定的资源位置(location)加载相应的资源。Resource 是 Spring 框架中另一个重要的接口,它代表一个可访问的资源,可以是文件、类路径资源、URL 等。

Spring 提供了多个实现 ResourceLoader 接口的类,包括:

  • DefaultResourceLoader: 默认的资源加载器,用于加载资源,支持类路径资源、文件系统资源等。
  • ClassPathResourceLoader: 用于加载类路径资源。
  • ServletContextResourceLoader: 用于在 Web 应用程序中加载 ServletContext 资源。
  • UrlResourceLoader: 用于加载 URL 资源。
  • 其他自定义的实现类,根据需要加载其他类型的资源。

在 Spring 应用程序中,通常通过 ResourceLoader 来加载资源,以获得更灵活的资源管理和访问方式。这样可以使代码与具体的资源位置解耦,并且能够轻松地在不同环境中切换资源的加载方式。

以下是一个简单的示例,展示如何使用 ResourceLoader 接口加载资源:

import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.DefaultResourceLoader;

public class ResourceLoaderExample {

    public static void main(String[] args) {
        // 创建资源加载器
        ResourceLoader resourceLoader = new DefaultResourceLoader();

        // 加载资源
        Resource resource = resourceLoader.getResource("classpath:example.txt");

        // 判断资源是否存在
        if (resource.exists()) {
            // 处理资源
            // ...
        } else {
            System.out.println("资源不存在。");
        }
    }
}

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

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

相关文章

vue新学习 02 vue命令v-model,数据代理,事件,监听,渲染

双向绑定用命令v-model&#xff1a; v-bind的命令是单项去绑定data中的相关属性&#xff0c;此时的data是真正的data&#xff0c;并没有用变量声明的方式去接收vue实例对象&#xff0c;也就是例如用const vm new Vue({})。而是直接就采用了new Vue&#xff08;{}&#xff09;这…

【DP】The 2022 ICPC Asia Regionals Online Contest (II) B Non-decreasing Array

PTA | 程序设计类实验辅助教学平台 题意&#xff1a; 给定一个不下降的序列&#xff0c;每次操作有两步&#xff1a; 1.选择2~N的一个数&#xff0c;删除这个数 2.选择2~N的一个数&#xff0c;改变这个数为任意值 要满足该数列不下降&#xff0c;N-2次询问&#xff0c;问操…

《玉骨遥》:腾讯视频定义古偶叙事及格线

&#xff08;图片来源于网络&#xff0c;侵删&#xff09; 文 | 螳螂观察 作者 | 郭襄 拿着自带话题与流量的古偶仙侠剧《玉骨遥》&#xff0c;腾讯视频着实做了一回暑期档的“显眼包”。 对于长视频平台来说&#xff0c;暑期档是兵家必争之地。但在一众竞争者中&#xff0…

3.操作元素内容

3.1元素innerText属性 ➢将文本内容 添加/更新到任意标签位置 ➢显示纯文本&#xff0c;不解析标签 【例如】 <body><div class"box">文字内容</div><script>// 1.获取元素const box document.querySelector(.box)// 2.修改文字内容 对象…

完全背包--动态规划

一)模板题:完全背包 【模板】完全背包_牛客题霸_牛客网 (nowcoder.com) 第一问: 一)定义一个状态表示: dp[i][j]表示从前i个物品中选&#xff0c;总体积不超过j&#xff0c;所有选法中&#xff0c;最大的价值 二)根据状态标识推到状态转移方程:根据最后一个位置的状态来划分问…

配置tomcat内存大小(windows、linux)

一、参数说明 -Xms&#xff1a; JVM初始分配的堆内存 -Xmx&#xff1a; JVM最大允许分配的堆内存&#xff0c;按需分配 -XX:PermSize&#xff1a; JVM初始分配的非堆内存 -XX:MaxPermSize&#xff1a; JVM最…

华为openGauss数据库入门 - gsql用法

目录 1.1 gsql的语法 1.2 gsql常用选项 1.2.1 最常用的必要选项 1.2.2 -r选项 1.2.3 -E选项 1.2.4 -t选项 1.2.5 -A选项 1.2.6 -v选项 1.2.7 -c选项 1.2.8 -f选项 1.2.9 -q选项 1.3 gsql的元命令 1.3.1 \l命令 1.3.2 \du命令和\dg命令 1.3.3 \db命令 1.3.4 \d…

flask部署钉钉机器人和企业微信机器人

引言 创建机器人&#xff0c;目的是通过机器人的方式&#xff0c;提出用户的问题&#xff0c;得到想要的回答 钉钉机器人 首先我们需要获取钉钉的企业内部开发者权限然后我们进入钉钉开放平台,登陆后&#xff0c;选择应用开发->机器人->创建应用&#xff0c;我创建了一…

用HTML写一个简单的静态购物网站

实现代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>购物网站</title> &l…

如何判断直线导轨的质量?

直线导轨是机械行业中的重要传动零部件&#xff0c;随着科技3.0时代的到来&#xff0c;直线导轨的需求量也在不断的增加&#xff0c;目前市面上直线导轨的品牌有很多&#xff0c;质量也是良莠不济&#xff0c;那么&#xff0c;我们应该怎样才能挑选到质量好的直线导轨呢&#x…

Python - OpenCV实现摄像头人脸识别(亲测版)

要使用Python 3和OpenCV进行摄像头人脸识别&#xff0c;您可以按照以下步骤进行操作&#xff1a; 1.安装OpenCV库 在命令行中输入以下命令&#xff1a; pip install opencv-python2.准备人脸检测器 使用OpenCV的人脸检测器可以检测出图像中的人脸。在Python中&#xff0c;您…

十一章:Weakly-Supervised Semantic Segmentation Network —— 基于深度种子区域增长的弱监督语义分割网络

0.摘要 本文研究了只使用图像级别标签作为监督来学习图像语义分割网络的问题&#xff0c;这是重要的&#xff0c;因为它可以显著减少人工标注的工作量。最近在这个问题上的最新方法首先使用深度分类网络推断出每个对象类的稀疏和有区别的区域&#xff0c;然后使用有区别的区域作…

const int * p,int const *p, int * const p, const int *const p 搞不清楚?

一、废话不多说&#xff0c;直接来结论 变量含义const int *p 指针p可以修改&#xff0c;*p不可修改int const *p 指针p可以修改&#xff0c;*p不可修改int *const p指针p不可以修改&#xff0c;*p可以修改const int * const p指针p不可以修改&#xff0c;*p不可以修改 显…

黑客学习手册(自学网络安全)

一、首先&#xff0c;什么是黑客&#xff1f; 黑客泛指IT技术主攻渗透窃取攻击技术的电脑高手&#xff0c;现阶段黑客所需要掌握的远远不止这些。 二、为什么要学习黑客技术&#xff1f; 其实&#xff0c;网络信息空间安全已经成为海陆空之外的第四大战场&#xff0c;除了国…

MES中的EAP有什么作用?

在现代制造业中&#xff0c;MES&#xff08;Manufacturing Execution System&#xff09;是一个关键的生产管理系统&#xff0c;用于监控、控制和优化制造过程。而EAP&#xff08;Equipment Automation Program&#xff09;作为MES的重要组成部分之一&#xff0c;在生产线上发挥…

DL优化器精简总结 | SGD, Momentum, AdaGrad, Rmsprop, Adam, AdamW

&#x1f525; DL里的优化器相关考点&#xff0c;面试时面试官偶尔会问甚至变态点的会叫代码手撕&#xff0c;笔试选择题只要跟DL相关基本必考。废话不多说&#xff0c;直接上&#xff01; &#x1f604; 当然并不是纯为了面试&#xff0c;只不过说你如果是搞DL的连优化器都说…

性能测试QPS+TPS+事务基础知识分析

本篇文章是性能测试基础篇&#xff0c;主要介绍了性能测试中对QPSTPS事务的基础知识分析&#xff0c;有需要的朋友可以借鉴参考下&#xff0c;希望可以对广大读者有所帮助 事务 就是用户某一步或几步操作的集合。不过&#xff0c;我们要保证它有一个完整意义。比如用户对某一个…

#P1009. [NOIP2016提高组] 玩具小人

题目描述 小南有一套可爱的玩具小人, 它们各有不同的职业。 有一天, 这些玩具小人把小南的眼镜藏了起来。 小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的面朝圈外。如下图: 这时 singer 告诉小南一个谜題: “眼镜藏在我左数第 33 个玩具小人的右数第 11 个玩具小人的…

CMU 15-445 -- Database Recovery - 18

CMU 15-445 -- Database Recovery - 18 引言ARIESLog Sequence NumbersNormal ExecutionTransaction CommitTransaction AbortCompensation Log Records Non-fuzzy & fuzzy CheckpointsSlightly Better CheckpointsFuzzy Checkpoints ARIES - Recovery PhasesAnalysis Phas…

第四范式x百胜软件 以生成式AI改造零售软件

7月20日&#xff0c;在百胜软件联合探路者举办的行业数字化转型研学活动上&#xff0c;百胜软件联合第四范式宣布将以「式说」大模型为核心&#xff0c;在软件智能化升级、行业赋能等方面开展深入合作&#xff0c;共同推动大模型在零售行业的创新与应用。 活动上&#xff0c;双…