广告
返回顶部
首页 > 资讯 > 前端开发 > node.js >如何掌握Spring
  • 379
分享到

如何掌握Spring

2024-04-02 19:04:59 379人浏览 薄情痞子
摘要

这篇文章主要讲解了“如何掌握spring”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何掌握Spring”吧!Spring 是一个控制反转依赖管理的容器,

这篇文章主要讲解了“如何掌握spring”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何掌握Spring”吧!

Spring 是一个控制反转依赖管理的容器,作为 JAVA WEB开发人员,基本没有不熟悉 Spring 技术栈的,尽管在依赖注入领域,Java  WEB 领域不乏其他优秀的框架,如 Google 开源的依赖管理框架 guice,如 Jersey web 框架等。但 Spring 已经是 Java Web  领域使用最多,应用最广泛的 Java 框架。

此文将专注讲解如何在 Spring 容器启动时实现我们自己想要实现的逻辑。我们时常会遇到在 Spring  启动的时候必须完成一些初始化的操作,如创建定时任务,创建连接池等。

如果没有 Spring 容器,不依赖于 Spring 的实现,回归 Java 类实现本身,我们可以在静态代码块,在类构造函数中实现相应的逻辑,Java  类的初始化顺序依次是静态变量 > 静态代码块 > 全局变量 > 初始化代码块 > 构造器。

比如,Log4j 的初始化,就是在 LogManager 的静态代码块中实现的:

static {     Hierarchy h = new Hierarchy(new RootLogger((Level) Level.DEBUG));     repositorySelector = new DefaultRepositorySelector(h);      String override =OptionConverter.getSystemProperty(DEFAULT_INIT_OVERRIDE_KEY,null);      if(override == null || "false".equalsIgnoreCase(override)) {           String configurationOptionStr = OptionConverter.getSystemProperty(DEFAULT_CONFIGURATION_KEY, null);           String configuratorClassName = OptionConverter.getSystemProperty(CONFIGURATOR_CLASS_KEY, null);            URL url = null;            if(configurationOptionStr == null) {             url = Loader.getResource(DEFAULT_XML_CONFIGURATION_FILE);             if(url == null) {               url = Loader.getResource(DEFAULT_CONFIGURATION_FILE);             }           } else {             try {               url = new URL(configurationOptionStr);             } catch (MalfORMedURLException ex) {               url = Loader.getResource(configurationOptionStr);             }           }            if(url != null) {             LogLog.debug("Using URL ["+url+"] for automatic log4j configuration.");             try {                 OptionConverter.selectAndConfigure(url, configuratorClassName,LogManager.getLoggerRepository());             } catch (NoClassDefFoundError e) {                 LogLog.warn("Error during default initialization", e);             }           } else {               LogLog.debug("Could not find resource: ["+configurationOptionStr+"].");           }     } else {             LogLog.debug("Default initialization of overridden by " +  DEFAULT_INIT_OVERRIDE_KEY + "property.");     } }

比如在构造函数中实现相应的逻辑:

@Component public class CustomBean {      @Autowired     private Environment env;      public CustomBean() {         env.getActiveProfiles();     } }

这里考验一下各位,上面的代码是否可以正常运行。—— 不行,构造函数中的env将会发生NullPointException异常。这是因为在 Spring  中将先初始化 Bean,也就是会先调用类的构造函数,然后才注入成员变量依赖的  Bean(@Autowired和@Resource注解修饰的成员变量),注意@Value等注解的配置的注入也是在构造函数之后。

PostConstruct

在 Spring 中,我们可以使用@PostConstruct在 Bean 初始化之后实现相应的初始化逻辑,@PostConstruct修饰的方法将在  Bean 初始化完成之后执行,此时 Bean 的依赖也已经注入完成,因此可以在方法中调用注入的依赖 Bean。

@Component public class CustomBean {      @Autowired     private Environment env;      @PostConstruce     public void init() {         env.getActiveProfiles();     } }

与@PostConstruct相对应的,如果想在 Bean 注销时完成一些清扫工作,如关闭线程池等,可以使用@PreDestroy注解:

@Component public class CustomBean {      @Autowired     private ExecutorService executor = Executors.newFixedThreadPool(1)      @PreDestroy     public void destroy() {         env.getActiveProfiles();     } }

InitializingBean

实现 Spring 的InitializingBean接口同样可以实现以上在 Bean  初始化完成之后执行相应逻辑的功能,实现InitializingBean接口,在afterPropertiesSet方法中实现逻辑:

@Component public class CustomBean implements InitializingBean {      private static final Logger LOG       = Logger.getLogger(InitializingBeanExampleBean.class);      @Autowired     private Environment environment;      @Override     public void afterPropertiesSet() throws Exception {         LOG.info(environment.getDefaultProfiles());     } }

ApplicationListener

我们可以在 Spring 容器初始化的时候实现我们想要的初始化逻辑。这时我们就可以使用到 Spring 的初始化事件。Spring  有一套完整的事件机制,在 Spring 启动的时候,Spring 容器本身预设了很多事件,在 Spring  初始化的整个过程中在相应的节点触发相应的事件,我们可以通过监听这些事件来实现我们的初始化逻辑。Spring 的事件实现如下:

  • ApplicationEvent,事件对象,由 ApplicationContext 发布,不同的实现类代表不同的事件类型。

  • ApplicationListener,监听对象,任何实现了此接口的 Bean 都会收到相应的事件通知。实现了 ApplicationListener  接口之后,需要实现方法 onApplicationEvent(),在容器将所有的 Bean 都初始化完成之后,就会执行该方法。

与 Spring Context 生命周期相关的几个事件有以下几个:

  • ApplicationStartingEvent: 这个事件在 Spring Boot  应用运行开始时,且进行任何处理之前发送(除了监听器和初始化器注册之外)。

  • ContextRefreshedEvent: ApplicationContext 被初始化或刷新时,该事件被发布。这也可以在  ConfigurableApplicationContext 接口中使用 refresh() 方法来发生。

  • ContextStartedEvent: 当使用 ConfigurableApplicationContext 接口中的 start() 方法启动  ApplicationContext 时,该事件被触发。你可以查询你的数据库,或者你可以在接受到这个事件后重启任何停止的应用程序。

  • ApplicationReadyEvent: 这个事件在任何 application/ command-line runners 调用之后发送。

  • ContextClosedEvent: 当使用 ConfigurableApplicationContext 接口中的 close() 方法关闭  ApplicationContext 时,该事件被触发。一个已关闭的上下文到达生命周期末端;它不能被刷新或重启。

  • ContextStoppedEvent: Spring 最后完成的事件。

因此,如果我们想在 Spring 启动的时候实现一些相应的逻辑,可以找到 Spring  启动过程中符合我们需要的事件,通过监听相应的事件来完成我们的逻辑:

@Component @Slf4j public class StartupApplicationListenerExample implements ApplicationListener<ContextRefreshedEvent> {      @Override     public void onApplicationEvent(ContextRefreshedEvent event) {         log.info("Subject ContextRefreshedEvent");     } }

除了通过实现ApplicationListener接口来监听相应的事件,Spring  的事件机制也实现了通过@EventListener注解来监听相对应事件:

@Component @Slf4j public class StartupApplicationListenerExample {      @EventListener     public void onApplicationEvent(ContextRefreshedEvent event) {         log.info("Subject ContextRefreshedEvent");     } }

Spring Event 是一套完善的进程内事件发布订阅机制,我们除了用来监听 Spring 内置的事件,也可以使用 Spring Event  实现自定义的事件发布订阅功能。

Constructor 注入

在学习 Spring 的注入机制的时候,我们都知道 Spring 可以通过构造函数、Setter  和反射成员变量注入等方式。上面我们在成员变量上通过@Autoware注解注入依赖 Bean,但是在 Bean 的构造函数函数中却无法使用到注入的 Bean(因为  Bean 还未注入),其实我们也是使用 Spring 的构造函数注入方式, 这也是 Spring 推荐的注入机制(在我们使用 idea  的时候,如果没有关闭相应的代码 Warning 机制,会发现在成员变量上的@Autoware是黄色的,也就是 idea 不建议的代码)。Spring  更推荐构造函数注入的方式:

@Component @Slf4j public class ConstructorBean {      private final Environment environment;      @Autowired     public LogicInConstructorExampleBean(Environment environment) {         this.environment = environment;         log.info(Arrays.asList(environment.getDefaultProfiles()));     } }

CommandLineRunner

如果我们的项目使用的是 Spring Boot,那么可以使用 Spring Boot 提供的 CommandLineRunner  接口来实现初始化逻辑,Spring Boot 将在启动初始化完成之后调用实现了CommandLineRunner的接口的run方法:

@Component @Slf4j public class CommandLineAppStartupRunner implements CommandLineRunner {      @Override     public void run(String...args) throws Exception {         log.info("Increment counter");     } }

并且,多个CommandLineRunner实现,可以通过@Order来控制它们的执行顺序。

SmartLifecycle

还有一种更高级的方法来实现我们的逻辑。这可以 Spring 高级开发必备技能哦。SmartLifecycle  不仅仅能在初始化后执行一个逻辑,还能再关闭前执行一个逻辑,并且也可以控制多个 SmartLifecycle  的执行顺序,就像这个类名表示的一样,这是一个智能的生命周期管理接口。

  • start():bean 初始化完毕后,该方法会被执行。

  • stop():容器关闭后,spring 容器发现当前对象实现了 SmartLifecycle,就调用 stop(Runnable), 如果只是实现了  Lifecycle,就调用 stop()。

  • isRunning:当前状态,用来判你的断组件是否在运行。

  • getPhase:控制多个 SmartLifecycle 的回调顺序的,返回值越小越靠前执行 start() 方法,越靠后执行 stop()  方法。

  • isAutoStartup():start 方法被执行前先看此方法返回值,返回 false 就不执行 start 方法了。

  • stop(Runnable):容器关闭后,spring 容器发现当前对象实现了 SmartLifecycle,就调用 stop(Runnable),  如果只是实现了 Lifecycle,就调用 stop()。

@Component public class SmartLifecycleExample implements SmartLifecycle {      private boolean isRunning = false;      @Override     public void start() {         System.out.println("start");         isRunning = true;     }      @Override     public int getPhase() {         // 默认为 0         return 0;     }      @Override     public boolean isAutoStartup() {         // 默认为 false         return true;     }      @Override     public boolean isRunning() {         // 默认返回 false         return isRunning;     }      @Override     public void stop(Runnable callback) {         System.out.println("stop(Runnable)");         callback.run();         isRunning = false;     }      @Override     public void stop() {         System.out.println("stop");          isRunning = false;     }  }

感谢各位的阅读,以上就是“如何掌握Spring”的内容了,经过本文的学习后,相信大家对如何掌握Spring这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

--结束END--

本文标题: 如何掌握Spring

本文链接: https://www.lsjlt.com/news/84056.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何掌握Spring
    这篇文章主要讲解了“如何掌握Spring”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何掌握Spring”吧!Spring 是一个控制反转依赖管理的容器,...
    99+
    2022-10-19
  • 如何掌握Spring中bean的生命周期!
    这期内容当中小编将会给大家带来有关如何掌握Spring中bean的生命周期!,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Spring 中bean 的生命周期短暂吗在spring中,从BeanFactor...
    99+
    2023-06-17
  • Java面试必备:如何掌握Spring和Unix?
    在Java开发领域,Spring框架是一个非常常用的框架,它可以帮助我们更加方便、快捷地开发Java应用程序。而Unix则是一个非常流行的操作系统,它广泛应用于服务器端和开发环境中。在Java面试中,掌握Spring和Unix是非常重要的...
    99+
    2023-09-16
    面试 spring unix
  • 一文快速掌握Spring Cloud Stream
    目录一、概述简介1.1. cloud Stream是什么1.2. 设计思想1.4. 注解二、基于注解代码练习2.1. 消息驱动之生产者2.3. 目前存在的问题2.4. 分组解决重复消...
    99+
    2022-11-13
  • Spring的IOC原理怎么掌握
    这篇文章主要介绍了Spring的IOC原理怎么掌握的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Spring的IOC原理怎么掌握文章都会有所收获,下面我们一起来看看吧。1 IOC的理论背景我们都知道,在采用面向...
    99+
    2023-07-02
  • 如何掌握Synchronized
    本篇内容主要讲解“如何掌握Synchronized”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何掌握Synchronized”吧!使用synchronized关键字是Java并发编程中线程同...
    99+
    2023-06-15
  • 如何掌握Promise
    本文小编为大家详细介绍“如何掌握Promise”,内容详细,步骤清晰,细节处理妥当,希望这篇“如何掌握Promise”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。异步编程想要学习promise,你必须要懂得什么是...
    99+
    2023-07-05
  • 如何掌握JSONP
    本篇内容主要讲解“如何掌握JSONP”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何掌握JSONP”吧! 一个正常的请求: JSON正常发请求时,c...
    99+
    2022-10-19
  • 如何学习和掌握 PHP Laravel 中的 Spring 函数?
    PHP Laravel 是目前最流行的 PHP 框架之一,拥有着强大的功能和灵活的扩展性。在 Laravel 中,Spring 函数是一个非常重要的概念,它可以帮助我们更方便地操作数据库并提高开发效率。本文将介绍如何学习和掌握 PHP La...
    99+
    2023-07-20
    laravel 函数 spring
  • 一文掌握Spring Boot 日志文件
    目录SpringBoot日志文件1. 日志有什么用2. 日志怎么用3. 自定义日志打印3.1 在程序中得到日志对象3.2 使用日志对象打印日志4. 日志级别4.1 日志级别有什么用?...
    99+
    2023-03-06
    Spring Boot 日志文件 Spring Boot 日志
  • Spring | 一文带你掌握IOC技术
    👑 博主简介:    🥇 Java领域新星创作者    🥇 阿里云开发者社区专家博主、星级博主、技术博主 🤝 交流社区:BoBoo...
    99+
    2023-09-02
    spring java
  • 一文掌握Spring的创建与使用
    目录Spring的创建1、创建Maven项目 2、添加Spring框架支持(spring-context,spring-beans) 3、添加启动类 S...
    99+
    2023-05-16
    Java Spring的创建与使用 Spring的创建 Spring的使用
  • Spring框架中Java函数的秘密:如何掌握它们?
    Spring框架是一个非常流行的Java应用程序开发框架,它提供了丰富的功能和工具,可以帮助开发人员更快地构建高质量的应用程序。其中,Java函数是Spring框架中最重要的部分之一,因为它们允许开发人员创建可重用的代码块,以便在整个应用...
    99+
    2023-09-16
    函数 spring 框架
  • 如何掌握ava反射
    这篇文章主要介绍“如何掌握ava反射”,在日常操作中,相信很多人在如何掌握ava反射问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何掌握ava反射”的疑惑有所帮助!接下来,...
    99+
    2022-10-19
  • 如何掌握JavaScript对象
    这篇文章主要介绍“如何掌握JavaScript对象”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“如何掌握JavaScript对象”文章能帮助大家解决问题。JavaS...
    99+
    2022-10-19
  • 如何掌握UML类图
    这篇文章主要介绍“如何掌握UML类图”,在日常操作中,相信很多人在如何掌握UML类图问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何掌握UML类图”的疑惑有所帮助!接下来,...
    99+
    2022-10-19
  • 如何掌握Java并发
    这篇文章主要介绍“如何掌握Java并发”,在日常操作中,相信很多人在如何掌握Java并发问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何掌握Java并发”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!1、...
    99+
    2023-06-15
  • 如何掌握Java泛型
    本篇内容介绍了“如何掌握Java泛型”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! 为什么要用泛型设想一个场景,我们希望用Java...
    99+
    2023-06-15
  • 如何掌握Java变量
    本篇内容介绍了“如何掌握Java变量”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!01、局部变量在方法体内声明的变量被称为局部变量,该变量只...
    99+
    2023-06-16
  • Java 程序员掌握 Spring Boot非常有必要
    Spring Boot从天而降 Spring Boot是企业级开发的整体整合解决方案,在现在企业项目开发中使用非常普遍,Spring Boot 2.0 的推出又激起了一阵学习 Spr...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作