Spring深入分析容器接口作用

目录
  • 1.容器接口有哪些
  • 2.BeanFactory能干嘛
  • 3.ApplicationContext有哪些扩展功能
    • 3.1 MessageSource
    • 3.2 ResourcePatternResolver
    • 3.3 EnvironmentCapable
    • 3.4 ApplicationEventPublisher

1.容器接口有哪些

在Spring中,容器接口有BeanFactory 接口和ApplicationContext 接口

其继承关系如下(Ctrl + alt + u)

由这个继承关系图可以看出,ApplicationContext 接口是 BeanFactory 的子接口。它扩展了 BeanFactory 接口的功能

而BeanFactory 才是 Spring 的核心容器, 主要的 ApplicationContext 实现都【组合】了它的功能

那么在哪里可以看见ApplicationContext 类呢?

就在SpringBoot的启动类中可以看见

@SpringBootApplication
@MapperScan("com.lingnan.mapper")
public class TestSpringbootApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(TestSpringbootApplication.class, args);
    }
}

SpringApplication.run()方法的返回值,则是ApplicationContext 的子类ConfigurableApplicationContext,也就是Spring容器

使用debug模式,可以清晰看见ApplicationContext 里面有BeanFactory ,并且BeanFactory 有很多单例

2.BeanFactory能干嘛

使用快捷键Ctrl + n查找BeanFactory,然后使用Ctrl + F12即可查看BeanFactory的方法

可以看到,BeanFactory接口的方法看起来并不多,只有getBean

实际上控制反转、基本的依赖注入、直至 Bean 的生命周期的各种功能, 都由它的实现类提供

3.ApplicationContext有哪些扩展功能

通过前面的ApplicationContext 的继承关系图,不难看出,ApplicationContext 比BeanFactory多继承了MessageSource、ResourcePatternResolver、EnvironmentCapable、ApplicationEventPublisher这几个接口

这几个接口也就是ApplicationEventPublisher的扩展功能

MessageSource接口是用来提供处理国际化资源的能力,可以识别多国语言,相当于翻译

ResourcePatternResolver接口提供的是通配符匹配资源(磁盘或者类路径下的文件)的能力

ApplicationEventPublisher接口则是可以用来发布事件对象

EnvironmentCapable接口提供了读取Spring的一些环境信息的能力

3.1 MessageSource

MessageSource提供了getMessage方法,可以将语言翻译成不同国家的语言

System.out.println(context.getMessage("hi", null, Locale.CHINA));
System.out.println(context.getMessage("hi", null, Locale.ENGLISH));
System.out.println(context.getMessage("hi", null, Locale.JAPANESE));

这里就能将hi翻译成中文、英语、日语

因为这个项目下提供了三个不同的文件,就会根据里面的键值对转化为对应的语言

3.2 ResourcePatternResolver

ResourcePatternResolver提供了getResources方法,可以根据路径或者通配符获取多个资源

public interface ResourcePatternResolver extends ResourceLoader {
	String CLASSPATH_ALL_URL_PREFIX = "classpath*:";
	Resource[] getResources(String locationPattern) throws IOException;
}

当然根据ResourcePatternResolver的父接口ResourceLoader,可以发现也可以获取单个资源

public interface ResourceLoader {
   String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;
   Resource getResource(String location);
e org.springframework.util.ClassUtils#forName(String, ClassLoader)
    */
   @Nullable
   ClassLoader getClassLoader();
}

下面举个栗子

Resource[] resources = context.getResources("classpath*:META-INF/spring.factories");
for (Resource resource : resources) {
    System.out.println(resource);
}

classpath是指当前类路径下(在jar包的话就需要像上面这样加*),而Resource是Spring中对资源的抽象

3.3 EnvironmentCapable

EnvironmentCapable提供了getEnvironment方法,获取当前Spring的配置信息(环境变量、application.properties等)

public interface EnvironmentCapable {
   /**
    * Return the {@link Environment} associated with this component.
    */
   Environment getEnvironment();
}

可以借助Environment的父接口PropertyResolver提供的getProperty方法获取某个配置信息

public interface Environment extends PropertyResolver {
   String[] getActiveProfiles();
   String[] getDefaultProfiles();
   @Deprecated
   boolean acceptsProfiles(String... profiles);
   boolean acceptsProfiles(Profiles profiles);
}

举个栗子

System.out.println(context.getEnvironment().getProperty("java_home"));
System.out.println(context.getEnvironment().getProperty("server.port"));

这样就能获取到环境变量和server.port端口号了

3.4 ApplicationEventPublisher

ApplicationEventPublisher的作用是用来发布事件的

@FunctionalInterface
public interface ApplicationEventPublisher {
   default void publishEvent(ApplicationEvent event) {
      publishEvent((Object) event);
   }
   void publishEvent(Object event);
}

ApplicationEventPublisher提供了一个publishEvent方法用来发布事件

而事件则需要继承ApplicationEvent,source代表事件源,也就是谁发的事件

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

然后就可以调用publishEvent来发送事件,参数为context,因为context是事件源,也就是context发的事件

context.publishEvent(new UserRegisteredEvent(context));

除了发事件,还应该有收事件的东西,也就是监听器

Spring中任何一个类都可以作为监听器

需要加上 @EventListener注解

然后参数为事件,也就是发的事件是什么类型,接收的事件也应该是什么类型

@Component
public class Component2 {
    private static final Logger log = LoggerFactory.getLogger(Component2.class);
    @EventListener
    public void aaa(UserRegisteredEvent event) {
        log.debug("{}", event);
        log.debug("发送短信");
    }
}

这样就可以了,其实这种操作很像mq,可以用来异步处理某些业务

比如我这里有一个注册方法,然后异步需要发送短信,那么发布事件之后,aaa方法就会异步执行

@Component
public class Component1 {
    private static final Logger log = LoggerFactory.getLogger(Component1.class);
    @Autowired
    private ApplicationEventPublisher context;
    public void register() {
        log.debug("用户注册");
        context.publishEvent(new UserRegisteredEvent(this));
    }
}

到此这篇关于Spring深入分析容器接口作用的文章就介绍到这了,更多相关Spring容器接口内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 大厂禁止SpringBoot在项目使用Tomcat容器原理解析

    目录 前言 SpringBoot中的Tomcat容器 SpringBoot设置Undertow Tomcat与Undertow的优劣对比 最后 前言 在SpringBoot框架中,我们使用最多的是Tomcat,这是SpringBoot默认的容器技术,而且是内嵌式的Tomcat.同时,SpringBoot也支持Undertow容器,我们可以很方便的用Undertow替换Tomcat,而Undertow的性能和内存使用方面都优于Tomcat,那我们如何使用Undertow技术呢?本文将为大家细细讲解

  • 介绍下Java Spring的核心接口,容器中Bean的实例化

    目录 Spring的核心接口 ApplicationContext接口 BeanFactory接口 Spring容器中Bean的实例化 构造方法 无参构造方法 有参构造方法 工厂 静态工厂 实例工厂 FactoryBean→使用工厂方法 总结 Spring的核心接口 ApplicationContext接口 继承了BeanFactory并且提供了加载资源文件的方法 ApplicationContext其实就是一个容器,ApplicationContext的实例其实就是容器对象,这个容器对象在实例

  • Spring通过工具类实现获取容器中的Bean

    目录 1. Aware 接口 2. BeanFactoryAware 3. TienChin 项目实践 1. Aware 接口 小伙伴们知道,Spring 容器最大的特点在于所有的 Bean 对于 Spring 容器的存在是没有意识的,因此我们常说理论上你可以无缝将 Spring 容器切换为其他容器(然而在现实世界中,我们其实没有这样的选择,除了 Spring 容器,难道还有更好用的?). 当然这只是一个理论,在实际开发中,我们往往要用到 Spring 容器为我们提供的诸多资源,例如想要获取到容

  • Spring源码解析容器初始化构造方法

    目录 前言 构造方法 前言 Spring框架被广泛应用于我们的日常工作中,但是很长时间以来我都是只会使用,不懂它的作用原理.通过最近一段时间的阅读源码,个人发现通过阅读源码,能够帮助我们了解Spring的设计理念,并且对Java编程中的一些设计模式更加熟悉,所以记录一下自己对Spring源码的理解. 在开始进行源码学习前,首先再回顾一下三种Spring编程风格: 基于Schema,即通过xml标签的配置方式 基于Annotation的注解技术,使用@Component等注解配置bean 基于Ja

  • Spring框架IOC容器底层原理详解

    目录 1.什么是IOC 2.IOC容器的底层原理 3.那么上边提到的三种技术如何实现IOC的呢 4.IOC(接口) 1.什么是IOC IOC – Inverse of Control,控制反转,将对象的创建权力反转给Spring框架! 在java当中一个类想要使用另一个类的方法,就必须在这个类当中创建这个类的对象,那么可能会出现如下情况, 比如A类当中创建着B对象,B类当中有C对象,C类当中有A对象,这个如果一个类出了问题,那么可能会导致这个框架出现问题. Spring 将创建对象的权利给了IO

  • 向Spring IOC 容器动态注册bean实现方式

    目录 本文的大纲 从一个需求谈起 Spring Bean的生命周期再完善 BeanDefinition Bean 加入IOC容器的几种方式 从spring容器中动态添加或移除bean 本文的大纲 从一个需求谈起 这周遇到了这样一个需求,从第三方的数据库中获取值,只是一个简单的分页查询,处理这种问题,我一般都是在配置文件中配置数据库的地址等相关信息,然后在Spring Configuration 注册数据量连接池的bean,然后再将数据库连接池给JdbcTemplate, 但是这种的缺陷是,假设填

  • Spring 容器初始化 register 与 refresh方法

    目录 register方法 refresh 方法 1.prepareRefresh 2.obtainFreshBeanFactory 3.prepareBeanFactory 4.postProcessBeanFactory 5.invokeBeanFactoryPostProcessors 6.registerBeanPostProcessors 7.非重点部分 前篇回顾: Spring源码解析容器初始化构造方法 在上一篇文章中,我们介绍完了AnnotationConfigApplicatio

  • Spring深入分析容器接口作用

    目录 1.容器接口有哪些 2.BeanFactory能干嘛 3.ApplicationContext有哪些扩展功能 3.1 MessageSource 3.2 ResourcePatternResolver 3.3 EnvironmentCapable 3.4 ApplicationEventPublisher 1.容器接口有哪些 在Spring中,容器接口有BeanFactory 接口和ApplicationContext 接口 其继承关系如下(Ctrl + alt + u) 由这个继承关系图

  • 详解JSP 中Spring工作原理及其作用

    详解JSP 中Spring工作原理及其作用 1.springmvc请所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责负责对请求进行真正的处理工作. 2.DispatcherServlet查询一个或多个HandlerMapping,找到处理请求的Controller. 3.DispatcherServlet请请求提交到目标Controller 4.Controller进行业务逻辑处理后,会返回一个ModelAndView 5.Dispathcher查询一个或多个

  • 详解常用的Spring Bean扩展接口

    前言 Spring是一款非常强大的框架,可以说是几乎所有的企业级Java项目使用了Spring,而Bean又是Spring框架的核心. Spring框架运用了非常多的设计模式,从整体上看,它的设计严格遵循了OCP----开闭原则,即: 1.保证对修改关闭,即外部无法修改Spring整个运作的流程 2.提供对扩展开放,即可以通过继承.实现Spring提供的众多抽象类与接口来改变类加载的行为 开卷有益,阅读Spring源码(无需每个类都看得很细,大体流程能梳理出来即可)对于个人水平的提升是帮助非常大

  • 使用Java注解模拟spring ioc容器过程解析

    使用注解,简单模拟spring ioc容器.通过注解给对象属性注入值. 项目结构 annotation 包,用于存放自定义注解 Component 注解表示该类为组件类,并需要声明名字 package priv.haidnor.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy;

  • 手把手教你写一个spring IOC容器的方法

    本文分享自华为云社区<手把手教你写一个spring IOC容器>,原文作者:技术火炬手. spring框架的基础核心和起点毫无疑问就是IOC,IOC作为spring容器提供的核心技术,成功完成了依赖的反转:从主类的对依赖的主动管理反转为了spring容器对依赖的全局控制.今天就带大家手写一个spring IOC容器. 第0步(准备工作): (1)JDK1.8及java环境变量 (2)maven包及maven环境变量 (3)idea 第1步(创建项目,引入tomcat包) PS:由于该项目的作用

  • springboot自动配置原理以及spring.factories文件的作用详解

    目录 一.springboot 自动配置原理 二.spring.factories文件的作用 spring.factories 的妙用 什么是 SPI 机制? Spring Boot 中的 SPI 机制 Spring Factories 实现原理是什么? Spring Factories 在 Spring Boot 中的应用 一.springboot 自动配置原理 先说说我们自己的应用程序中Bean加入容器的办法: package com.ynunicom.dc.dingdingcontract

  • Spring深入分析讲解BeanUtils的实现

    目录 背景 DO BO DTO VO 数据实体转换 使用方式 原理&源码分析 属性赋值类型擦除 总结 背景 DO DO是Data Object的简写,叫做数据实体,既然是数据实体,那么也就是和存储层打交道的实体类,应用从存储层拿到的数据是以行为单位的数据,不具备java特性,那么如果要和java属性结合起来或者说在业务中流转,那么一定要转换成java对象(反过来java要和持久层打交道也要把java对象转换成行数据),那么就需要DO作为行数据的一个载体,把行的每一个列属性映射到java对象的每一

  • Spring Java-based容器配置详解

    装Java-based的配置 使用 @Import 注解 跟在Spring XML文件中使用<import>元素添加模块化的配置类似,@Import注解允许你加载其他配置类中的@Bean定义: @Configuration public class ConfigA { @Bean public A a() { return new A(); } } @Configuration @Import(ConfigA.class) public class ConfigB { @Bean public

  • spring boot容器启动流程

    一.前言 spring cloud大行其道的当下,如果不了解基本原理那么是很纠结的(看见的都是 约定大于配置 ,但是原理呢?为什么要这么做?).spring cloud是基于spring boot快速搭建的,今天咱们就看看spring boot容器启动流程.(本文不讲解如何快速启动spring boot,那些直接官方看即可, 官网文档飞机票 ) 二.容器启动 spring boot一般是 指定容器启动main方法,然后以命令行方式启动Jar包 ,如下图: @SpringBootApplicati

随机推荐