SpringBoot中的扩展点

ApplicationContextInitializer的initialize方法。

时机 : 所有的配置文件都已经加载,spring容器还没被刷新之前 准备阶段 this.prepareContext(context, environment, listeners, applicationArguments, printedBanner); 

它允许开发人员在Spring应用上下文(ApplicationContext)被创建和刷新之前,对上下文进行自定义的初始化设置。通过实现ApplicationContextInitializer接口,您可以执行以下类型的自定义功能:

  1. 定制ApplicationContext配置

    • 添加或修改ApplicationContext的属性。
    • 设置环境变量(Environment)或系统属性。
    • 注册自定义的PropertySources,以便在上下文初始化时注入自定义的属性值。
  2. 注册额外的Bean Definition

    • 在Spring IoC容器初始化之前预先注册自定义的Bean,这样在容器启动时就可用。
    • 注册自定义的BeanPostProcessorAdvisor等,用于增强或修改容器中其他Bean的行为。
  3. 定制资源加载

    修改上下文的资源加载策略,例如添加自定义的ResourceLoader或修改其默认行为。
  4. 初始化第三方库或中间件

    初始化与Spring容器一起使用的第三方库或中间件,例如数据库连接池、缓存服务、消息队列客户端等。
  5. 初始化应用级基础设施

    设置应用启动时所需的基础设施,如初始化日志框架、加密服务、国际化设置等。
  6. 执行特定的初始化逻辑

    执行一次性的初始化动作,比如配置系统层面的设定、读取外部配置文件并注入到环境中等。

示例代码如下:

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.core.env.ConfigurableEnvironment;

public class CustomApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        // 获取环境对象
        ConfigurableEnvironment environment = applicationContext.getEnvironment();
        
        // 设置或修改环境属性
        environment.getPropertySources().addFirst(new MyCustomPropertySource());

        // 注册自定义的Bean
        applicationContext.registerBean("customBean", CustomBean.class);

        // 执行其他初始化逻辑
        // ...
    }
}
BeanDefinitionRegistryPostProcessor

refresh()的 this.invokeBeanFactoryPostProcessors(beanFactory);此时此bean的定义信息 都已经加载完毕 但是还没到实例化以及初始化阶段。

主要用于在Spring IoC容器初始化过程中对Bean定义进行进一步的加工或扩展,可以拓展的功能包括但不限于:

  1. 添加自定义Bean定义

    在容器完成所有默认的Bean定义扫描和注册之后,但在任何Bean实例化之前,可以动态地向容器中注册新的Bean定义,这对于实现动态扩展Bean的集合非常有用。
  2. 修改现有的Bean定义

    改变Bean的属性,如修改构造函数参数、修改Bean的scope(作用域)、修改初始化方法或销毁方法等。
  3. 删除不必要的Bean定义

    根据运行时条件或配置,可以选择性地移除已经注册的Bean定义,避免某些Bean实例化和初始化。
  4. 调整Bean之间的依赖关系

    动态地更改Bean之间的依赖关系,例如添加额外的depends-on属性,确保Bean按期望的顺序初始化。
  5. 配置元数据处理

    处理基于注解的Bean定义,例如解析自定义注解并据此更新Bean定义的元数据。
  6. 处理第三方库或遗留系统的Bean定义

    当第三方库没有使用Spring的@Component注解,但又需要纳入Spring容器管理时,可以使用BeanDefinitionRegistryPostProcessor来注册这些类为Spring Bean。
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

@Configuration
public class CustomBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        // 注册新的Bean定义
        GenericBeanDefinition customBeanDef = new GenericBeanDefinition();
        customBeanDef.setBeanClass(CustomBean.class);
        registry.registerBeanDefinition("customBean", customBeanDef);

        // 修改已有Bean定义
        BeanDefinition existingBeanDef = registry.getBeanDefinition("someExistingBean");
        existingBeanDef.setAttribute("customAttribute", "newValue");

        // 删除Bean定义
        if (registry.containsBeanDefinition("toBeDeletedBean")) {
            registry.removeBeanDefinition("toBeDeletedBean");
        }
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        // 此方法也可以进行一些工厂级别的后处理,但主要用于处理BeanFactory而非BeanDefinitionRegistry
    }
}

我们老是讲BeanDefinition,那么它是啥呢?

BeanDefinition是IoC(Inversion of Control,控制反转)容器的基本组成单元,它描述了Spring容器中Bean的元信息。每个由Spring容器管理的Bean都有一个对应的BeanDefinition对象,它包含了Bean的所有必要配置信息,如:

  1. Bean 类型(Class):定义了Bean的具体实现类。
  2. 作用域(Scope):定义了Bean的生命周期模式,如singleton(单例)或prototype(原型)。
  3. 构造器参数和属性值:Bean依赖的其他Bean,或者是直接的属性值。
  4. 初始化方法和销毁方法:定义了Bean实例化后要调用的初始化方法和容器关闭前要调用的销毁方法。
  5. 是否懒加载:指示Bean是否应在首次请求时才创建实例。
  6. 自定义属性:其他用户自定义的属性信息。

bean是怎么变成beandefinition的呢?Spring容器在启动和初始化过程中,会将各种来源的Bean配置信息转换成BeanDefinition对象,主要包括以下几个步骤:

  1. XML配置文件

    当使用XML配置方式时,Spring容器读取XML配置文件,通过BeanDefinitionParserDelegate等组件解析XML标签,将标签内的配置信息转换成BeanDefinition对象。
  2. 注解驱动配置

    当使用注解如@Component@Service@Repository@Controller等进行配置时,Spring通过组件扫描(@ComponentScan)自动检测到带有这些注解的类,并使用ClassPathBeanDefinitionScanner或其他类似组件将类转换成对应的BeanDefinition
  3. Java配置类

    在Java配置类(如带有@Configuration注解的类)中,通过@Bean注解的方法声明的Bean,Spring会自动处理这些方法并将方法体中的逻辑转换成BeanDefinition。Spring Boot中ConfigurationClassPostProcessor会处理这些Java配置类。
  4. 手动注册

    在代码中手动创建GenericBeanDefinition等BeanDefinition子类实例,填充相关信息后,通过DefaultListableBeanFactory或其他BeanDefinitionRegistry接口的实现注册到Spring容器。
BeanFactoryPostProcessor

允许开发者在Bean实例化之前对Spring IoC容器中的Bean定义进行修改和扩展。通过实现BeanFactoryPostProcessor接口,您可以拓展以下功能:

  1. 修改Bean属性

    动态修改Bean定义中的属性值,例如修改构造器参数值、属性值、初始化方法、销毁方法等。
  2. 自定义Bean作用域

    更改Bean的作用域(Scope),如将Singleton Bean改为Prototype Bean,或者自定义作用域。
  3. 注入额外的依赖

    动态地向Bean定义中注入额外的依赖,而不必在代码中显式声明。
  4. 配置属性替换

    能够根据运行时环境或配置文件动态替换Bean定义中的占位符属性值。
  5. 实现Bean的动态代理

    可以在Bean实例化前为其生成代理类,添加额外的横切逻辑,如AOP(面向切面编程)的增强功能。
  6. 处理遗留系统的Bean定义

    对于一些不遵循Spring规范的遗留系统,可以通过BeanFactoryPostProcessor将遗留系统中的类注册为Spring Bean,并进行必要的配置。
  7. 整合第三方库配置

    在Bean实例化前,整合第三方库的相关配置,将其无缝融入Spring IoC容器的管理。

示例代码:

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.stereotype.Component;

@Component
public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        String[] beanNames = beanFactory.getBeanDefinitionNames();
        for (String beanName : beanNames) {
            BeanDefinition bd = beanFactory.getBeanDefinition(beanName);
            // 示例:修改某Bean定义的属性值
            if ("someBean".equals(beanName)) {
                bd.getPropertyValues().addPropertyValue("propertyName", "newPropertyValue");
            }
        }
    }
}

那么BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor看起来好像是,有啥区别呢?BeanDefinitionRegistryPostProcessor 它继承了 BeanFactoryPostProcessor 接口。

BeanFactoryPostProcessor:

  • 主要功能:允许开发人员在 Spring 容器完成所有标准 Bean 定义的读取之后但在任何 Bean 实例化之前修改这些 Bean 定义。
  • 改动范围:可以修改现有 Bean 定义的各种属性,包括但不限于构造函数参数、属性值、依赖关系等。
  • 应用场景:例如,可以用来替代配置文件中的占位符属性值,或者进行全局性的属性设置。

BeanDefinitionRegistryPostProcessor:

  • 扩展功能:除了具有 BeanFactoryPostProcessor 的能力之外,还能够注册新的 Bean 定义。
  • 特殊权限:它可以直接操作 BeanDefinitionRegistry,这意味着可以在初始化过程的更早阶段添加或删除 Bean 定义。
  • 应用场景:当需要动态添加、移除或修改整个 Bean 定义集合时特别有用,比如在扫描特定包下带有自定义注解的类并将其自动注册为 Spring Bean 的场景。

总结来说,两者的主要区别在于:

  • BeanFactoryPostProcessor 更专注于修改已有的 Bean 定义属性。
  • BeanDefinitionRegistryPostProcessor 不仅能修改,还能在 Spring 容器构建过程中增加新的 Bean 定义,提供了更高的定制化程度。

执行顺序方面,BeanDefinitionRegistryPostProcessor 先于 BeanFactoryPostProcessor 执行。这样设计的原因在于,确保在 Bean 定义的最终集合形成后,再给所有 Bean 定义提供一个统一修改的机会。最后,所有经过这些后置处理器处理过的 Bean 定义才会被用来创建实际的 Bean 实例。

BeanPostProcessor

它允许开发者在 Spring 容器创建 Bean 实例后,但在 Bean 初始化前后对其进行自定义处理。通过实现 BeanPostProcessor 接口,可以拓展以下功能:

  1. 字段注入或方法调用

    在 Bean 初始化之前或之后添加额外的属性注入,或者调用自定义方法。
  2. AOP 切面增强

    实现面向切面编程(AOP),在 Bean 创建后,对其进行代理,添加横切关注点,如事务管理、日志记录、权限控制等。
  3. 对象包装

    将 Bean 包装成代理对象,以实现在调用 Bean 方法时附加额外的逻辑。
  4. 懒加载优化

    实现自定义的懒加载策略,延迟某些 Bean 的初始化时间点。
  5. 属性修改

    在 Bean 初始化前后,修改 Bean 实例的属性值。
  6. 初始化前后自定义逻辑

    在 Bean 初始化前后执行自定义的初始化或清理逻辑。
  7. 自定义依赖注入

    根据自定义逻辑动态注入 Bean 的依赖,而非仅依赖于 Spring 的默认注入机制。

具体实现这两个方法:

  • Object postProcessBeforeInitialization(Object bean, String beanName): 在 Bean 初始化(调用 InitializingBean 接口的 afterPropertiesSet() 方法或 @PostConstruct 注解的方法)之前调用。

  • Object postProcessAfterInitialization(Object bean, String beanName): 在 Bean 初始化之后调用,但在 Bean 准备好被应用上下文使用之前调用。

如下例子将展示如何在 Spring 容器中创建 Bean 实例之后对其内容进行自定义操作。这里我们将创建一个简单的后处理器,它会打印 Bean 的名称和类名,并对具有特定注解的 Bean 进行额外处理。

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.stream.Collectors;

@Component
public class LoggingBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("Bean '" + beanName + "' is being created. Bean class: " + bean.getClass().getName());
        
        // 检查Bean是否带有特定注解,如果有,则进行特殊处理
        if (bean.getClass().isAnnotationPresent(MySpecialAnnotation.class)) {
            // 假设MySpecialAnnotation注解存在并有一些自定义逻辑
            processSpecialBean(bean);
        }

        return bean; // 返回未经修改的原始Bean对象,也可以返回一个包装过的Bean
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("Bean '" + beanName + "' has been initialized.");
        return bean; // 返回未经修改的原始Bean对象,同样可以返回一个包装过的Bean
    }

    private void processSpecialBean(Object bean) {
        // 假设这里的逻辑是对标注了MySpecialAnnotation的Bean的字段进行赋值或其它操作
        Class<?> clazz = bean.getClass();
        Arrays.stream(clazz.getDeclaredFields())
              .filter(field -> field.isAnnotationPresent(MySpecialAnnotation.class))
              .forEach(field -> {
                  try {
                      field.setAccessible(true);
                      // 这里进行自定义的字段赋值或其他操作
                      // ...
                  } catch (IllegalAccessException e) {
                      throw new RuntimeException("Error processing annotated field in bean", e);
                  }
              });
    }

    // 假设的自定义注解
    @interface MySpecialAnnotation {
        // 注解的属性...
    }
}
InitializingBean

允许我们在 Bean 实例化后和依赖注入完成后,被其他bean依赖或者执行前执行一些自定义的初始化逻辑。通过实现 InitializingBean 接口,可以拓展以下功能:

  1. 自定义初始化操作

    执行额外的数据校验、初始化状态设置、与其他Bean交互或建立内部依赖关系等操作。
  2. 执行一次性初始化任务

    在Bean准备就绪投入服务之前,执行必需的一次性初始化任务,如打开数据库连接、初始化缓存、设置定时任务等。
  3. 注入后处理

    当依赖注入完成后,可以基于注入的属性执行一些初始化逻辑。

具体执行顺序如下:

  1. Spring 容器创建 Bean 实例。
  2. 容器对 Bean 进行依赖注入(DI),也就是填充所有通过 Setter 方法、构造函数或其他注解标记的属性。
  3. 如果 Bean 实现了 InitializingBean 接口,Spring 容器接下来会调用 afterPropertiesSet() 方法。
  4. 如果 Bean 上使用了 @PostConstruct 注解的方法,这些方法将在 InitializingBean.afterPropertiesSet() 之后执行。
  5. 如果 Bean 在 XML 配置中或通过 @Configuration 类定义了一个 init-method,那么这个 init-method 方法也会在这之后执行。

下面是一个简单的 InitializingBean 接口实现的例子:

import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

@Component
public class MyComponent implements InitializingBean {

    private String property1;
    private int property2;

    // 通过@Autowired注解或者其他方式注入属性
    public void setProperty1(String property1) {
        this.property1 = property1;
    }

    public void setProperty2(int property2) {
        this.property2 = property2;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        // 在所有属性注入完成后,执行自定义的初始化逻辑
        System.out.println("MyComponent has been instantiated with property1=" + property1 + " and property2=" + property2);

        // 模拟一个初始化操作,比如初始化数据库连接
        // ...

        // 或者进行数据验证
        if (property1 == null || property1.isEmpty()) {
            throw new IllegalArgumentException("Property1 must not be empty!");
        }
    }
}
@PostConstruct , @PreDestroy

@PostConstruct

  • 该注解用于标记在一个无参的实例方法上,表示在依赖注入完成后,但在 Bean 正式投入使用(即任何业务方法被调用前)时执行的方法。
  • 这个注解的方法通常用于初始化 Bean 的内部状态,如数据库连接、初始化缓存、加载配置等。
  • 示例:
import javax.annotation.PostConstruct;
import org.springframework.stereotype.Component;

@Component
public class MyComponent {

    @PostConstruct
    public void init() {
        System.out.println("Bean is being initialized...");
        // 执行初始化逻辑
    }

    // ...其他方法
}

@PreDestroy

  • 该注解用于标记在一个无参的实例方法上,表示在 Bean 生命周期结束时,即将从 Spring 容器中移除之前执行的方法。
  • 这个注解的方法通常用于资源清理,如关闭数据库连接、清除缓存、保存状态、发送关闭通知等。
  • 示例:
import javax.annotation.PreDestroy;
import org.springframework.stereotype.Component;

@Component
public class MyComponent {

    // ...其他方法

    @PreDestroy
    public void cleanup() {
        System.out.println("Bean is about to be destroyed...");
        // 执行资源清理逻辑
    }
}

注意:在 Spring 中,@PostConstruct 和 @PreDestroy 注解的方法的执行顺序优先级高于 InitializingBean 和 DisposableBean 接口中的 afterPropertiesSet() 和 destroy() 方法,以及在 XML 配置中定义的 init-method 和 destroy-method。

BeanNameAware

BeanNameAware 是 Spring Framework 提供的一个接口,允许 Bean 实例了解自己在 Spring 容器中的 bean 名称。当一个类实现了 BeanNameAware 接口后,Spring 容器在实例化该 Bean 并注入其属性后,会调用 setBeanName() 方法,传递给 Bean 其在 Spring 配置文件中定义的 bean 名称。

示例:

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;

public class MyBean implements BeanNameAware {

    private String myBeanName;

    @Override
    public void setBeanName(String name) {
        this.myBeanName = name;
        System.out.println("Bean Name is: " + name);
    }

    // ...其他方法
}

在上面的例子中,当 Spring 容器创建 MyBean 实例时,会自动调用 setBeanName() 方法,将当前 Bean 的名字传递给 myBeanName 字段。这个特性在一些需要知道自身 Bean 名称以进行特定逻辑处理的场景中会很有用。

InstantiationAwareBeanPostProcessor

它扩展了 BeanPostProcessor 接口,提供了在 Bean 实例化阶段进行介入和定制的能力。通过实现 InstantiationAwareBeanPostProcessor 接口,除非有特殊情况,否则Spring容器中大部分由Spring管理创建的Bean在实例化过程中都会受到InstantiationAwareBeanPostProcessor的监测和处理,可以实现以下功能:

  1. 自定义实例化过程

    通过重写 postProcessBeforeInstantiation(Class<?> beanClass, String beanName) 方法,在 Spring 创建 Bean 实例之前有机会自定义实例化过程,甚至可以返回一个自定义的 Bean 实例,从而替代 Spring 默认的实例化过程。
  2. 修改初始化后的 Bean 实例

    同样作为 BeanPostProcessor 的一部分,可以重写 postProcessBeforeInitialization(Object bean, String beanName) 和 postProcessAfterInitialization(Object bean, String beanName) 方法,在 Bean 初始化前后进行自定义处理。
  3. 决定是否提前暴露早期引用

    通过实现 getEarlyBeanReference(Object bean, String beanName) 方法,可以在 Bean 初始化之前决定是否提前暴露该 Bean 的早期引用给其他 Bean 使用。
  4. AOP(面向切面编程)支持

    在某些情况下,例如在实现 AOP 代理时,需要在 Bean 实例化阶段就能创建代理对象,而不是等待常规的 Bean 初始化阶段。InstantiationAwareBeanPostProcessor 为此类场景提供了支持。

示例:

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;

public class CustomInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if (YourCustomCondition.check(beanClass)) {
            return new YourCustomBeanImplementation();
        }
        return null; // 返回null表示仍然使用Spring默认的实例化方式
    }

    // ...其他BeanPostProcessor方法的实现
}

InstantiationAwareBeanPostProcessor 相对于 BeanPostProcessor 提供了更早的介入时机,允许在 Bean 实例化阶段就进行自定义处理。通过实现 InstantiationAwareBeanPostProcessor,可以实现诸如自定义实例化过程、提前修改属性值等高级定制需求。

它们在作用时机上有微妙的区别:

  1. BeanPostProcessor:

    • BeanPostProcessor 接口提供了在 Spring 容器创建 Bean 实例并完成依赖注入之后,但在调用初始化方法(如 @PostConstruct 注解的方法或者 InitializingBean 接口的 afterPropertiesSet() 方法)之前和之后执行自定义逻辑的机会。
    • 有两个关键方法:
      • postProcessBeforeInitialization(Object bean, String beanName):在 Bean 初始化前调用。
      • postProcessAfterInitialization(Object bean, String beanName):在 Bean 初始化后调用。
  2. InstantiationAwareBeanPostProcessor:

    • InstantiationAwareBeanPostProcessor 是 BeanPostProcessor 的一个子接口,它在 Bean 实例化阶段提供了更多的介入点。
    • 在 Bean 实例化前后,除了拥有 BeanPostProcessor 的全部功能外,还提供了如下方法:
      • postProcessBeforeInstantiation(Class<?> beanClass, String beanName):在 Spring 实际创建 Bean 实例之前调用。如果这个方法返回非空对象,那么 Spring 将不再使用默认的实例化策略,而是使用返回的对象作为 Bean 实例。
      • postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName):在实例化后、初始化前修改 Bean 属性值的阶段调用,允许在注入属性值之后,初始化方法调用之前修改属性值。
有哪些接口在spring启动过程中只执行一次呢?

在Spring框架中,当你想在Spring Boot应用程序启动时只执行一次某些代码,有几种常见的接口和机制可以使用。以下是几种常见的方法:

  1. @PostConstruct 注解
    这是最常用的方法之一。你可以在任何Bean的方法上使用@PostConstruct注解,这样该方法就会在Bean初始化完成后自动被调用。这通常用于执行只需在启动时执行一次的操作,如初始化数据或配置。

    1. @Component  
      public class StartupRunner {  
      
          @PostConstruct  
          public void init() {  
              // 这里编写启动时需要执行的代码  
          }  
      }

  2. CommandLineRunner 或 ApplicationRunner 接口
    这两个接口都定义了一个run方法,Spring Boot会在所有Spring Beans都初始化完成后调用这个方法。CommandLineRunner的参数是命令行参数数组,而ApplicationRunner的参数是ApplicationArguments对象,后者提供了对命令行参数的更多控制。

    1. @Component  
      public class MyCommandLineRunner implements CommandLineRunner {  
      
          @Override  
          public void run(String... args) throws Exception {  
              // 这里编写启动时需要执行的代码  
          }  
      }
  3. @EventListener 注解与 ApplicationReadyEvent
    你可以通过监听ApplicationReadyEvent事件来在Spring Boot应用程序完全启动后执行代码。这个事件在应用程序的上下文刷新并且所有的beans都已经初始化之后触发。

    1. @Component  
      public class StartupListener {  
      
          @EventListener(ApplicationReadyEvent.class)  
          public void onApplicationEvent(ApplicationReadyEvent event) {  
              // 这里编写启动时需要执行的代码  
          }  
      }
  4. InitializingBean 接口
    虽然这个接口在Spring中已经被使用了很长时间,但在Spring Boot应用程序中,通常更倾向于使用@PostConstruct注解或CommandLineRunner接口。不过,它仍然是一个有效的选择。

    1. @Component  
      public class MyInitializingBean implements InitializingBean {  
      
          @Override  
          public void afterPropertiesSet() throws Exception {  
              // 这里编写启动时需要执行的代码  
          }  
      }
  5. 在XML配置文件中使用init-method属性
    如果你使用XML配置文件而不是Java配置,你可以通过在bean定义中添加init-method属性来指定初始化方法。不过,在Spring Boot中,这种做法并不常见。

  • 7
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值