论Spring或Spring Boot的花式扩展

引言

Spring Boot是一个高度可定制的框架,旨在帮助开发者快速创建、配置和管理他们的应用程序

扩展点讲述

Spring Boot的扩展点主要在于它允许开发者自定义和扩展其功能。例如,你可以通过创建自定义的自动配置类来覆盖或添加新的自动配置;或者通过实现Spring Boot的ApplicationContextAware或CommandLineRunner等接口来添加自定义的应用程序逻辑;此外,你还可以通过创建自定义的starter来封装和提供特定的依赖项集合。下面我将为大家介绍这三类自定义扩展的基本实现思路或案例

花式扩展之自动配置类

  1. 创建一个配置类,并在类上添加 @Configuration 注解。
  2. 在该配置类中创建需要注册的 Bean,并使用 @Bean 注解标注该方法。
  3. 如果需要配置属性,可以创建一个配置属性类,并在类上添加 @ConfigurationProperties 注解。该注解的 prefix 属性指定了配置属性的前缀。
  4. 在配置类中使用 @EnableConfigurationProperties 注解来启用该配置属性类。
  5. 如果需要条件化地注册 Bean,可以使用 @Conditional 注解来指定一个条件。
  6. 如果需要指定一个 Bean 只在一个特定的 profile 处于激活状态时才会被注册,可以在 Bean 的定义方法上添加 @Profile 注解,并指定需要激活的 profile。
  7. 如果需要自动装配 Bean 依赖,可以在属性或 setter 方法上添加 @Autowired 注解。
  8. 如果需要注入具有指定名称的 Bean,可以在属性上添加 @Resource 注解,并指定需要注入的 Bean 的名称。

花式扩展之实现接口

实现方式

  • ApplicationContextInitializer:用于自定义应用程序上下文的初始化过程。
  • SpringBootApplicationProcessor:用于自定义Spring Boot应用程序的配置。通过实现该接口并使用自定义逻辑,您可以修改Spring Boot应用程序的配置类。
  • EnvironmentPostProcessor:用于自定义Spring环境的初始化和配置过程。通过实现该接口,您可以定义一个类,该类将在Spring环境创建之前或创建过程中被调用,允许您对环境变量的设置、配置文件的加载等进行自定义或修改。
  • ResourceLoaderAware:提供对ResourceLoader的引用,让Bean可以访问到资源加载器
  • ApplicationContextAware:提供ApplicationContext的引用,让Bean可以访问到应用程序上下文。
  • ApplicationArguments:用于获取应用程序的命令行参数
  • BeanNameGenerator:自定义Bean的名称生成策略。
  • BeanDefinitionRegistryPostProcessor:允许在BeanDefinitionRegistry中注册所有的Bean之前执行一些自定义处理。
  • BeanPostProcessor:允许在Bean的生命周期中进行一些自定义处理,比如自动装配和后处理。
  • BeanFactoryPostProcessor:允许在BeanFactory初始化之前执行一些自定义处理,比如改变Bean的定义或替换其他Bean。
  • EnvironmentAware:提供对SpringEnvironment的引用,让Bean可以访问到应用程序的环境信息。
  • Initializer:用于在Bean的生命周期开始时执行一些自定义操作。
  • ApplicationListener:监听ApplicationEvent的发布,用于响应应用程序级别的事件。
  • MessageSourceAware:提供对MessageSource的引用,让Bean可以访问到国际化消息。
  • BeanFactoryAware:提供对BeanFactory的引用,让Bean可以访问到Bean工厂。
  • ApplicationContextAware:提供对ApplicationContext的引用,让Bean可以访问到应用程序上下文。
  • ServletContextAware:提供对ServletContext的引用,让Bean可以访问到Web应用程序的上下文。
  • BeanDestroyedHandler:在Bean的生命周期结束时执行一些自定义操作。
  • Lifecycle:定义了Bean的生命周期接口,允许开发者在关键的生命周期方法(如初始化、销毁等)上执行一些自定义操作。
  • CustomEditorConfigurer:允许定义自定义属性编辑器,用于将属性类型转换为适合的编辑器。
  • ResourcePatternResolver:用于解析资源路径,以便找到指定的资源。
  • BeanDefinitionReader:用于读取Bean定义信息,包括XML和Java配置类等。
  • BeanDefinitionRegistry:用于管理Bean定义的注册和解析。
  • BeanDefinitionDecoder:用于解码Bean定义信息,将其转换为可操作的Bean对象。
  • BeanDefinitionDocumentReader:用于读取XML配置文件中的Bean定义信息。
  • BeanDefinitionParser:用于解析特定类型的配置文件(如XML或Java类)。
  • BeanDefinitionHolder:包含Bean定义和其相关的名称、别名等信息。
  • BeanDefinitionVisitor:用于访问和操作Bean定义信息。
  • BeanDefinitionReaderListener:监听Bean定义读取事件,用于在读取过程中执行一些自定义操作。
  • BeanDefinitionRegistryListener:监听Bean定义注册事件,用于在注册过程中执行一些自定义操作。
  • BeanDefinitionParserDelegate:提供了一些辅助方法来帮助解析和校验Bean定义信息。
  • BeanDefinitionValidationVisitor:用于校验Bean定义的合法性。
  • BeanNameGeneratorHolder:包含一个BeanNameGenerator和一个BeanNameGeneratorDelegate。
  • BeanFactoryInitializerAdapter:允许通过BeanFactory实现BeanFactoryInitializr接口的功能。
  • LifeCycleProcessor:用于在Bean的生命周期中执行自定义操作,比如在Bean的生命周期事件发生时执行特定的逻辑。
  • CommandLineRunner:用于在应用程序启动后执行自定义的命令行逻辑。通过实现该接口,您可以定义一个类,在该类的run方法中编写自定义逻辑,以便在应用程序启动后执行特定的操作。
  • ApplicationRunner:与CommandLineRunner类似,用于在应用程序启动后执行自定义逻辑。与CommandLineRunner不同的是,ApplicationRunner更适用于复杂的命令行参数处理和输出结果的处理。
  • WebMvcConfigurer:用于自定义Spring MVC的配置。通过实现该接口并重写addConventions方法,您可以自定义Spring MVC的约定,比如自定义控制器路径、异常处理等。
  • AsyncConfigurer:用于自定义异步方法的配置。通过实现该接口并重写getAsyncExecutor方法,您可以自定义异步执行的线程池配置,比如线程池大小、线程池类型等。

样例

@SpringBootApplication
@Slf4j
public class J4nJspApplication implements ApplicationContextAware , BeanNameGenerator , BeanDefinitionRegistryPostProcessor, BeanPostProcessor, BeanFactoryPostProcessor
, EnvironmentAware, CommandLineRunner {
    public static void main(String[] args) {
        SpringApplication.run(J4nJspApplication.class, args);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        log.info("获取上下文进行操作");
    }

    @Override
    public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
        log.info("我可以改变bean的名称");
        return null;
    }

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        log.info("我可以获取容器并修改bean或添加bean");
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        log.info("提供了bean definition的解析和注册功能,可以解析配置文件中定义的Bean只是我的功能之一而已");
    }

    @Override
    public void setEnvironment(Environment environment) {
        log.info("环境变量{}", JSONUtil.toJsonStr(environment));
    }

    @Override
    public void run(String... args) throws Exception {
        log.info("我可以在项目启动后执行一些操作");
    }
}

花式扩展之自定义starter

Import方式

  • @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @Import(AutoConfigurationxxxx.class)
    public @interface EnableAutoConfiguration {}
  • AutoConfigurationxxxx implements BeanFactoryAware, EnvironmentAware, Ordered ...
  • 启动类标记@EnableAutoConfiguration

SpringFactories方式

  • 新建文件 resources/META-INFO/spring.factories
  • 文件配置 org.springframework.boot.autoconfigure.EnableAutoConfiguration=你的配置类包路径.配置类,xxx,xxx,xxx ,多个配置类逗号分隔

总结

  • 自动配置:Spring 的自动配置功能可以帮助开发者快速搭建应用程序框架,但是有时候默认的配置可能不能满足实际需求。通过自定义扩展,开发者可以提供自己的自动配置代码,覆盖默认配置,以满足特定的应用需求。
  • 实现接口:Spring 提供了许多接口和抽象类,开发者可以通过实现这些接口来自定义扩展功能。通过实现接口,开发者可以定制自己的业务逻辑,增强 Spring 功能,提高应用程序的灵活性和可维护性。
  • starters:Spring Boot 的 starters是 Spring 提供的一种快速启动项目的方式,它提供了一些常用的依赖库,使得开发者在启动项目时不需要手动添加这些依赖。通过自定义扩展,开发者可以添加自己的 starters,提供更多的功能和库支持,使得其他开发者能够更方便地使用自己的项目。

鸣谢

  • 非常感谢你从头到尾阅读了这篇文章,希望其中的内容对你有所启发和帮助。如果你还有其他问题或需要进一步的了解,欢迎随时关注我的动态并留言
  • 最后可以给作者点个关注和小赞赞嘛,谢谢!
相关推荐
m0_5719575828 分钟前
Java | Leetcode Java题解之第543题二叉树的直径
java·leetcode·题解
魔道不误砍柴功3 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2343 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨3 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
种树人202408193 小时前
如何在 Spring Boot 中启用定时任务
spring boot
测开小菜鸟4 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
P.H. Infinity5 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天5 小时前
java的threadlocal为何内存泄漏
java
caridle5 小时前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express
^velpro^5 小时前
数据库连接池的创建
java·开发语言·数据库