初始化源码
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {~~~setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));~~~
}private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {// 获取当前 SpringApplication 实例的类加载器// 这个类加载器将用于加载类和资源ClassLoader classLoader = getClassLoader();// 从 META-INF/spring.factories 文件中加载指定类型的工厂类名称// 使用 LinkedHashSet 保证加载的类名称的顺序,并且去除重复项// SpringFactoriesLoader.loadFactoryNames(type, classLoader) 会读取 spring.factories 文件中指定类型的类名称Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));// 根据加载的类名称,反射创建指定类型的实例// createSpringFactoriesInstances 方法会根据类名称和构造函数参数类型及参数值,反射创建实例List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);// 根据 @Order 注解或实现 Ordered 接口的顺序对实例进行排序// AnnotationAwareOrderComparator.sort(instances) 会根据 @Order 注解或 Ordered 接口的值对实例进行排序AnnotationAwareOrderComparator.sort(instances);// 返回创建并排序后的实例集合return instances;
}
SpringApplication中 initializers
钩子实现
1. 实现 ApplicationContextInitializer
接口
你需要创建一个类,实现 ApplicationContextInitializer
接口,并在 initialize
方法中实现自定义的初始化逻辑。
public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {// 在这里执行自定义逻辑System.out.println("Executing custom logic before Spring context refresh");// 例如,设置环境变量ConfigurableEnvironment environment = applicationContext.getEnvironment();environment.setProperty("custom.property", "customValue");}
}
2. 注册初始化器
你可以在 SpringApplication
的构造方法中显式注册这些初始化器,或者通过 META-INF/spring.factories
文件自动发现它们。
显式注册
在 SpringApplication
的构造方法中显式注册初始化器:
public class MyApplication {public static void main(String[] args) {SpringApplication application = new SpringApplication(MyApplication.class);// 显式注册初始化器application.addInitializers(new MyApplicationContextInitializer());application.run(args);}
}
通过 META-INF/spring.factories
文件自动发现
在 resources
目录下创建或编辑 META-INF/spring.factories
文件,并添加你的初始化器类:
org.springframework.context.ApplicationContextInitializer=\
com.example.MyApplicationContextInitializer
初始化器的执行顺序
ApplicationContextInitializer
:在 Spring 容器刷新之前执行。ApplicationRunner
和CommandLineRunner
:在 Spring 容器刷新之后执行。
ApplicationListener
是 Spring 提供的一个接口,用于监听 Spring 应用上下文中的事件。通过实现ApplicationListener
接口,你可以捕获并处理特定的事件,从而在 Spring 应用的生命周期中执行自定义逻辑。
以下是使用 ApplicationListener
钩子的步骤和示例代码:
SpringApplication中listeners 钩子实现
ApplicationListener接口继承自Java的EventListener接口,表示一个事件监听器,它能够接收并处理特定类型的事件。在Spring中,当一个事件被发布时(通常是通过ApplicationContext的publishEvent方法),Spring会查找所有实现了ApplicationListener接口并且声明了要监听的事件类型的Bean,然后调用这些Bean的onApplicationEvent方法来处理事件。
1. 实现 ApplicationListener
接口
你需要创建一个类,实现 ApplicationListener
接口,并重写 onApplicationEvent
方法。onApplicationEvent
方法会在事件发生时被调用。
示例代码
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;@Component
public class MyApplicationListener implements ApplicationListener<ApplicationReadyEvent> {@Overridepublic void onApplicationEvent(ApplicationReadyEvent event) {// 在这里执行自定义逻辑System.out.println("Application is ready and fully started!");// 你可以在这里执行一些初始化逻辑或检查}
}
2. 监听特定事件
Spring 提供了多种事件类型,例如:
ContextRefreshedEvent
:在 Spring 容器刷新时触发。ApplicationReadyEvent
:在 Spring 应用完全启动后触发。ContextStartedEvent
:在 Spring 容器启动时触发。ContextStoppedEvent
:在 Spring 容器停止时触发。ContextClosedEvent
:在 Spring 容器关闭时触发。
你可以选择监听特定的事件类型。例如,如果你想在应用启动后执行一些逻辑,可以监听 ApplicationReadyEvent
。
3. 自定义事件
你还可以定义自己的事件类型,并在需要的时候发布这些事件。
定义自定义事件
import org.springframework.context.ApplicationEvent;public class MyCustomEvent extends ApplicationEvent {private String message;public MyCustomEvent(Object source, String message) {super(source);this.message = message;}public String getMessage() {return message;}
}
发布自定义事件
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;@Service
public class MyService {@Autowiredprivate ApplicationEventPublisher eventPublisher;public void doSomething() {// 执行一些业务逻辑System.out.println("Doing something...");// 发布自定义事件MyCustomEvent customEvent = new MyCustomEvent(this, "Custom event message");eventPublisher.publishEvent(customEvent);}
}
监听自定义事件
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;@Component
public class MyCustomEventListener implements ApplicationListener<MyCustomEvent> {@Overridepublic void onApplicationEvent(MyCustomEvent event) {// 在这里处理自定义事件System.out.println("Received custom event: " + event.getMessage());}
}
4. 使用注解方式监听事件
除了实现 ApplicationListener
接口,你还可以使用 @EventListener
注解来监听事件。