关于springboot:知识整理Springboot启动扩展点

40次阅读

共计 8755 个字符,预计需要花费 22 分钟才能阅读完成。

SpringBoot 启动扩大点整顿

1. 前言

​ 在 Springboot 服务启动阶段,Springboot 提供了许多扩大点。在理论的业务开发过程中,局部非凡的业务需要须要再 Springboot 服务启动过程中动静的加载配置或者执行业务解决,特此将罕用的 Springboot 启动扩大点做一个简略的整顿。

2. 筹备阶段


2.1 EnvironmentPostProcessor

  • 接口门路

org.springframework.boot.env.EnvironmentPostProcessor

  • 官网阐明

    • 容许在刷新应用程序上下文之前自定义应用程序的 Environment
    • 须要在 META-INF/spring.factories 文件中定义

Allows for customization of the application’s {@link Environment} prior to the application context being refreshed.

EnvironmentPostProcessor implementations have to be registered in {@code META-INF/spring.factories}, using the fully qualified name of this class as the key.

  • 利用场景

​ 能够加载自定义的配置文件并增加至 Environment 中

  • 回调机会
  • 代码示例
public class DemoEnvironmentPostProcessor implements EnvironmentPostProcessor {

    @Override
    public void postProcessEnvironment(@NonNull ConfigurableEnvironment environment, @NonNull SpringApplication application) {System.out.println(">>> 执行 EnvironmentPostProcessor.postProcessEnvironment()办法");
    }
}
  • 失效形式

​ 在 META-INF/spring.factories 文件中增加内容

org.springframework.boot.env.EnvironmentPostProcessor = com.example.demo.extension.DemoEnvironmentPostProcessor

2.2 ApplicationContextInitializer

  • 接口门路

org.springframework.context.ApplicationContextInitializer

  • 利用场景

​ Spring 会在容器刷新之前调用此类的 initialize 办法,能够激活一些配置或者获取 Enviroment 进行一些业务解决。

  • 回调机会
  • 代码示例
public class DemoApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    @Override
    public void initialize(@NonNull ConfigurableApplicationContext applicationContext) {System.out.println(">>> 执行 ApplicationContextInitializer.initialize()办法");
    }
}
  • 失效形式

    META-INF/spring.factories 文件中增加内容

    org.springframework.context.ApplicationContextInitializer = com.example.demo.extension.DemoApplicationContextInitializer

3. 刷新上下文容器阶段

​ 这部分的接口在执行 refreshContext(context) 办法刷新上下文的过程中回调。

3.1 BeanDefinitionRegistryPostProcessor

  • 接口门路

org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor

  • 利用场景

​ 这个接口在读取我的项目中的 beanDefinition 之后执行,提供一个补充的扩大点,动静注册本人的beanDefinition,能够加载 classpath 之外的 bean。

  • 回调机会
  • 代码示例
@Component
public class DemoBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(@NonNull BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {System.out.println(">>> 执行 BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()办法");
    }

    @Override
    public void postProcessBeanFactory(@NonNull ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {System.out.println(">>> 执行 BeanDefinitionRegistryPostProcessor.postProcessBeanFactory()办法");
    }
}

3.2 BeanFactoryPostProcessor

  • 接口门路

org.springframework.beans.factory.config.BeanFactoryPostProcessor

  • 利用场景

​ 这个接口是 beanFactory 的扩大接口,调用机会在 spring 在读取 beanDefinition 信息之后,实例化 bean 之前。在这个机会,用户能够通过实现这个扩大接口来自行处理一些货色,比方批改曾经注册的 beanDefinition 的元信息。

  • 回调机会

​ 在 AbstractApplicationContext 类的 refresh 办法中被执行。

  • 代码示例
@Component
public class DemoBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(@NonNull ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {System.out.println(">>> 执行 BeanFactoryPostProcessor.postProcessBeanFactory()办法");
    }
}

3.3 BeanFactoryAware 和 EnvironmentAware

  • 接口门路

org.springframework.beans.factory.BeanFactoryAware

org.springframework.context.EnvironmentAware

  • 利用场景

​ 在 bean 实例化和属性注入之后执行,能够在 bean 初始化之前注入 BeanFactoryEnvironment 等在初始化阶段应用。

  • 回调机会

​ 在 AbstractAutowireCapableBeanFactory 类的 createBean 办法创立 bean 的过程中执行。

  • 代码示例
@Component
public class DemoBeanFactoryAware implements BeanFactoryAware {

    @Override
    public void setBeanFactory(@NonNull BeanFactory beanFactory) throws BeansException {System.out.println(">>> 执行 BeanFactoryAware.setBeanFactory()办法");
    }
}
@Component
public class DemoEnvironmentAware implements EnvironmentAware {

    @Override
    public void setEnvironment(@NonNull Environment environment) {System.out.println(">>> 执行 EnvironmentAware.setEnvironment()办法");
    }
}

3.4 InstantiationAwareBeanPostProcessor

  • 接口门路

org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor

  • 利用场景

InstantiationAwareBeanPostProcessor接口在 BeanPostProcessor 接口的根底上又扩大了 3 个办法,共蕴含 5 个办法,能够在 bean 的实例化前后,属性注入阶段以及初始化前后进行业务解决。例如 Springboot 中就是通过 BeanPostProcessor 的实现类来解析 bean 中带有 @KafkaListener 注解的办法来注册 Kafka 容器。

  • 回调机会

    • postProcessBeforeInstantiation 办法:在 bean 实例化之前执行
    • postProcessAfterInstantiation 办法:在 bean 实例化之后执行
    • postProcessProperties 办法:在 bean 属性注入阶段执行
    • postProcessBeforeInitialization 办法:在 bean 初始化之前执行
    • postProcessAfterInitialization 办法:在 bean 初始化之后执行
  • 代码示例
@Component
public class DemoInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

    @Override
    public Object postProcessBeforeInstantiation(@NonNull Class<?> beanClass, @NonNull String beanName) throws BeansException {if (beanClass == DemoService.class) {System.out.println(">>> 执行 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()办法");
        }
        return InstantiationAwareBeanPostProcessor.super.postProcessBeforeInstantiation(beanClass, beanName);
    }

    @Override
    public boolean postProcessAfterInstantiation(@NonNull Object bean, @NonNull String beanName) throws BeansException {if (bean instanceof DemoService) {System.out.println(">>> 执行 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()办法");
        }
        return InstantiationAwareBeanPostProcessor.super.postProcessAfterInstantiation(bean, beanName);
    }

    @Override
    public PropertyValues postProcessProperties(@NonNull PropertyValues pvs, @NonNull Object bean, @NonNull String beanName) throws BeansException {if (bean instanceof DemoService) {System.out.println(">>> 执行 InstantiationAwareBeanPostProcessor.postProcessProperties()办法");
        }
        return InstantiationAwareBeanPostProcessor.super.postProcessProperties(pvs, bean, beanName);
    }

    @Override
    public Object postProcessBeforeInitialization(@NonNull Object bean, @NonNull String beanName) throws BeansException {if (bean instanceof DemoService) {System.out.println(">>> 执行 InstantiationAwareBeanPostProcessor.postProcessBeforeInitialization()办法");
        }
        return InstantiationAwareBeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    @Override
    public Object postProcessAfterInitialization(@NonNull Object bean, @NonNull String beanName) throws BeansException {if (bean instanceof DemoService) {System.out.println(">>> 执行 InstantiationAwareBeanPostProcessor.postProcessAfterInitialization()办法");
        }
        return InstantiationAwareBeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}

3.5 @PostConstruct 注解

  • 注解门路

javax.annotation.PostConstruct

  • 利用场景

​ 能够在 bean 的初始化阶段执行初始化办法进行业务解决。

  • 回调机会

​ 在 AbstractAutowireCapableBeanFactory 类的 createBean 办法创立 bean 的过程中 InitDestroyAnnotationBeanPostProcessor 类的 postProcessBeforeInitialization 办法中执行。

  • 代码示例
@Service
public class DemoService {

    @PostConstruct
    public void init() {System.out.println(">>> 执行 @PostConstruct 注解办法");
    }
}

3.6 InitializingBean

  • 接口门路

org.springframework.beans.factory.InitializingBean

  • 利用场景

​ 同样能够在执行 bean 初始化过程中执行业务解决。

  • 回调机会

​ 在 AbstractAutowireCapableBeanFactory 类的 createBean 办法创立 bean 的过程中 AbstractAutowireCapableBeanFactory 类的 initializeBean 办法中执行。

  • 代码示例
@Component
public class DemoInitializingBean implements InitializingBean {

    @Override
    public void afterPropertiesSet() throws Exception {System.out.println(">>> 执行 InitializingBean.afterPropertiesSet()办法");
    }
}

3.7 SmartInitializingSingleton

  • 接口门路

org.springframework.beans.factory.SmartInitializingSingleton

  • 利用场景

​ 在对所有单例对象初始化结束后,做一些后置的业务解决。

  • 回调机会

​ 在类 DefaultListableBeanFactorypreInstantiateSingletons的办法中执行。

  • 代码示例
@Component
public class DemoSmartInitializingSingleton implements SmartInitializingSingleton {

    @Override
    public void afterSingletonsInstantiated() {System.out.println(">>> 执行 SmartInitializingSingleton.afterSingletonsInstantiated()办法");
    }
}

3.8 SmartLifecycle

  • 接口门路

org.springframework.context.SmartLifecycle

  • 利用场景

​ 在对所有单例对象初始化结束后,做一些后置的业务解决。SmartLifecycleLifecycle 接口的根底上,扩大了 3 个办法。

​ 其中,isAutoStartup()办法返回 true 时,Bean 将在容器实现刷新阶段执行 Lifecycle 接口的 start() 办法;getPahase()办法用于返回 SmartLifecycle 的优先级。可联合配置文件的配置项来指定 SmartLifecycle 是否主动启动及启动的优先级。

  • 回调机会

​ 在 AbstractApplicationContext 类的 finishRefresh 办法中执行。

  • 代码示例
@Component
public class DemoSmartLifecycle implements SmartLifecycle {

    @Override
    public void start() {System.out.println(">>> 执行 SmartLifecycle.start()办法");
    }

    @Override
    public void stop() {}

    @Override
    public boolean isRunning() {return false;}
}

4. 执行程序

​ 通过日志能够看到各个扩大点的理论执行程序。

>>> 执行 EnvironmentPostProcessor.postProcessEnvironment()办法

>>> 执行 ApplicationContextInitializer.initialize()办法

>>> 执行 BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()办法

>>> 执行 BeanDefinitionRegistryPostProcessor.postProcessBeanFactory()办法

>>> 执行 BeanFactoryPostProcessor.postProcessBeanFactory()办法

>>> 执行 BeanFactoryAware.setBeanFactory()办法
 
>>> 执行 EnvironmentAware.setEnvironment()办法

>>> 执行 InitializingBean.afterPropertiesSet()办法

>>> 执行 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()办法

>>> 执行 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()办法

>>> 执行 InstantiationAwareBeanPostProcessor.postProcessProperties()办法

>>> 执行 InstantiationAwareBeanPostProcessor.postProcessBeforeInitialization()办法

>>> 执行 @PostConstruct 注解办法

>>> 执行 InstantiationAwareBeanPostProcessor.postProcessAfterInitialization()办法

>>> 执行 SmartInitializingSingleton.afterSingletonsInstantiated()办法

>>> 执行 SmartLifecycle.start()办法

正文完
 0