谈谈Spring boot 启动层面的开发

Spring boot的启动可以主要分为2个阶段。1
是调用AbstractApplicationContext的refresh方法之前和调用AbstractApplicationContext的refresh。

我们知道AbstractApplicationContext的refresh的方法是一个模板方法。几乎所有类型的ApplicationContext的初始化都是围绕这个refresh方法来进行。

1. refresh方法之前

1.1 ApplicationContextInitializer

这个类Spring
boot最先进行调用的类,其主要就是初始化一些BeanFactoryPostProcessor(后面会说明),或者一些在Application
初始化的时候就需要做的事情。而这些类通过通过扫描calsspath路径下的:META-INF/spring.factories
文件中的org.springframework.context.ApplicationContextInitializer字来加载类的全路径名,通过反射获取对象,然后调用initialize方法。

1.2 ApplicationListener

这个和ApplicationContextInitializer加载的方式类似,也是从META-INF/spring.factories文件中的配置,主要作用就是在Spring

boot的初始化不同阶段会处罚不同的事件(ApplicationEvent及其子类),而这些监听器就会根据自己在不同事件触发的情况下完成自己的处理逻辑。例如,ConfigFileApplicationListener负责加载配置文件。

当然也可以通过其他方式加入beanFactory中,详情可以参照BeanFactoryPostProcessor加入到beanFactory的方法

1.ApplicationListener的有些事件是在ApplicationContextInitializer之前触发的

2.建议不要直接在ApplicationContextInitializer加入自己的BeanFactoryPostProcessor方法,xxxAware是不会帮你注入的。

2. refresh方法

这个就是spring的模板方法,主要有3个比较重要的接口

2.1 BeanFactoryPostProcessor

public interface BeanFactoryPostProcessor {
    
   void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

这个方法就是给可以对beanFactory进行一些自定义的操作,例如加入一些bean等。当然前提就是我们定义的bean是在beanFactory中。有许多办法可以做到

  •  在ApplicationContextInitializer中定义加入,例如
public class MyContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    public void initialize(ConfigurableApplicationContext applicationContext) {
        applicationContext.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor());
    }

}
  • 通过其他BeanFactoryPostProcessor加入,可以通过注解@Import或者加载XML)

例如通过@Import(value={AnnotationBeanDefinitionRegistrar.class})

@Configuration
public class AnnotationBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    private String BEAN_NAME = "annotationBeanPostProcessor";

    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        List<String> basePackages = getPackagesToScan(importingClassMetadata);
        if (!registry.containsBeanDefinition(BEAN_NAME)) {
            addPostProcessor(registry, basePackages);
        }
    }

    private void addPostProcessor(BeanDefinitionRegistry registry, List<String> basePackages) {
        GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
        beanDefinition.setBeanClass(AnnotationBeanPostProcessor.class);
        beanDefinition.getConstructorArgumentValues()
                .addGenericArgumentValue(basePackages);
        beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
        registry.registerBeanDefinition(BEAN_NAME, beanDefinition);
    }

    private List<String> getPackagesToScan(AnnotationMetadata metadata) {
        AnnotationAttributes attributes = AnnotationAttributes.fromMap(
                metadata.getAnnotationAttributes(EnableDubbo.class.getName()));
        String[] basePackages = attributes.getStringArray("basePackages");
        return Arrays.asList(basePackages);
    }
}

这样,就可以加入我们自定义的BeanFactoryPostProcessor,就可以在Bean注册的层面上进行开发

2.2 BeanPostProcessor

public interface BeanPostProcessor {

   Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;

   Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;

}

这个接口主要就是针对在bean实例化前后做一些定制开发。一般只针对某个接口或者某个注解进行批量操作

3. 综述

1. 如果你需要在SpringApplication初始化的时候就做一些事情,使用ApplicationContextInitializer

2. 如果你需要SpringApplication的某个特定阶段做一些事情,使用ApplicationListener(推荐)

3. 如果你需要在beanFactory层面上开发,使用BeanFactoryPostProcessor(推荐)

4. 如果你需要在对某个bean的实例化层面上开发,使用BeanPostProcessor(一般业务上的开发使用InitializingBean或者init-method能够满足)

作者:lizo

来源:51CTO

时间: 2024-12-24 08:41:05

谈谈Spring boot 启动层面的开发的相关文章

Spring Boot 启动端口如何启动_java

Spring Boot 启动端口 Spring Boot 其默认是集成web容器的,启动方式由像普通Java程序一样,main函数入口启动.其内置Tomcat容器或Jetty容器,具体由配置来决定(默认Tomcat).当然你也可以将项目打包成war包,放到独立的web容器中(Tomcat.weblogic等等),当然在此之前你要对程序入口做简单调整. spring boot是个好东西,可以不用容器直接在main方法中启动,而且无需配置文件,方便快速搭建环境.可是当我们要同时启动2个springb

用Spring Boot颠覆Java应用开发

Java开发概述: 使用Java做Web应用开发已经有近20年的历史了,从最初的Servlet1.0一步步演化到现在如此多的框架,库以及整个生态系统.经过这么长时间的发展,Java作为一个成熟的语言,也演化出了非常成熟的生态系统,这也是许多公司采用Java作为主流的语言进行服务器端开发的原因,也是为什么Java一直保持着非常活跃的用户群.然而这个生态系统纷繁复杂,一个非常简单的Java Web应用程序都有可能应用到以下技术: Java开发分为两个阵营,一个是由Oracle 为代表的Java EE

Spring boot 启动过程解析 logback

使用 Spring Boot 默认的日志框架 Logback. 所有这些 POM 依赖的好处在于为开发 Spring 应用提供了一个良好的基础.Spring Boot 所选择的第三方库是经过考虑的,是比较适合产品开发的选择.但是 Spring Boot 也提供了不同的选项,比如日志框架可以用 Logback 或 Log4j,应用服务器可以用 Tomcat 或 Jetty. http://www.ibm.com/developerworks/cn/java/j-lo-spring-boot/ sp

Spring Boot 启动加载数据 CommandLineRunner

实际应用中,我们会有在项目服务启动的时候就去加载一些数据或做一些事情这样的需求. 为了解决这样的问题,Spring Boot 为我们提供了一个方法,通过实现接口 CommandLineRunner 来实现. 很简单,只需要一个类就可以,无需其他配置. 创建实现接口 CommandLineRunner 的类 package org.springboot.sample.runner; import org.springframework.boot.CommandLineRunner; import

spring boot应用启动原理分析

spring boot quick start 在spring boot里,很吸引人的一个特性是可以直接把应用打包成为一个jar/war,然后这个jar/war是可以直接启动的,不需要另外配置一个Web Server. 如果之前没有使用过spring boot可以通过下面的demo来感受下. 下面以这个工程为例,演示如何启动Spring boot项目: git clone git@github.com:hengyunabc/spring-boot-demo.git mvn spring-boot

《深入实践Spring Boot》一第1章Spring Boot入门1.1 配置开发环境

第1章 Spring Boot入门 在使用Spring Boot框架进行各种开发体验之前,要先配置好开发环境.首先安装JDK,然后选择一个开发工具,如Eclipse IDE和IntelliJ IDEA(以下简称IDEA)都是不错的选择.对于开发工具的选择,本书极力推荐使用IDEA,因为它为Spring Boot提供了许多更好和更贴切的支持,本书的实例都是使用IDEA创建的.同时,还需要安装Apache Maven和Git客户端.所有这些都准备好之后,我们就能开始使用Spring Boot了. 1

深入实践Spring Boot导读

Preface?前 言 Spring Boot作为Java编程语言的一个全新开发框架,在国内外才刚刚兴起,还未得到普及使用.相比于以往的一些开发框架,Spring Boot不但使用更加简单,而且功能更加丰富,性能更加稳定而健壮.使用Spring Boot开发框架,不仅能提高开发速度,增强生产效率,从某种意义上,可以说是解放了程序员的劳动,而且一种新技术的使用,更能增强系统的稳定性和扩展系统的性能指标.本书就是本着提高开发效率,增强系统性能,促进新技术的普及使用这一目的而写的. Spring Bo

Spring Data JPA方法定义规范【从零开始学Spring Boot】

视频&交流平台] à SpringBoot网易云课堂视频 http://study.163.com/course/introduction.htm?courseId=1004329008 à Spring Boot交流平台 http://412887952-qq-com.iteye.com/blog/2321532           事情的起因:有人问过我们这个这个问题:为什么我利用Spring data jpa写的方法没有按照我想要的情况进行执行呢?我记得当时只是告诉他你你先看看Spring

了解Spring Boot的自动配置

Spring Boot的自动配置给开发者带来了很大的便利,当开发人员在pom文件中添加starter依赖后,maven或者gradle会自动下载很多jar包到classpath中.当Spring Boot检测到特定类的存在,就会针对这个应用做一定的配置,自动创建和织入需要的spring bean到程序上下文中. 在之前的文章中,我们只是在pom文件中增加各种starter的依赖,例如:spring-boot-starter-data-jpa, spring-boot-starter-web, s