import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.PropertySource; import org.springframework.core.io.support.ResourcePropertySource; import java.io.IOException; /** * @description 修改Spring Boot默认的environment属性。使用configurableApplicationContext.getEnvironment()方法获取到environment对象,从而修改环境变量,例如添加自定义配置文件路径。 */ public class InterveneApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { @Override public void initialize(ConfigurableApplicationContext configurableApplicationContext) { //堆代码 duidaima.com ConfigurableEnvironment environment = configurableApplicationContext.getEnvironment(); // 添加自定义配置文件路径 try { ObjectMapper objectMapper = new ObjectMapper(); System.out.println("InterveneApplicationContextInitializer initialize :" + configurableApplicationContext); environment.getPropertySources().addFirst(new ResourcePropertySource("classpath:zyftest.properties")); System.out.println("InterveneApplicationContextInitializer initialize add FirstResourcePropertySource classpath:zyftest.properties"); } catch (IOException e) { e.printStackTrace(); } } }在上面的代码中,我们通过getEnvironment()方法获取到ConfigurableEnvironment对象,然后通过getPropertySources()方法获取到属性源,使用addFirst()方法将自定义的custom.properties文件的PropertySource添加到属性源的首位。这样,在应用程序启动时,就会首先加载custom.properties文件,从而实现了自定义的配置。
org.springframework.context.ApplicationContextInitializer= org.zyf.javabasic.springextend.runext.InterveneApplicationContextInitializer添加自定义的PropertySource
import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.PropertySource; import org.springframework.core.io.support.ResourcePropertySource; import java.io.IOException; /** * @description 添加自定义的PropertySource。使用environment.getPropertySources().addLast(propertySource)方法,可以添加自定义的属性源,从而实现更灵活的配置。 */ public class InterveneApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { @Override public void initialize(ConfigurableApplicationContext configurableApplicationContext) { // 添加自定义的PropertySource PropertySource<?> propertySource = new MyPropertySource("myPropertySource"); environment.getPropertySources().addLast(propertySource); System.out.println("InterveneApplicationContextInitializer initialize add PropertySource myPropertySource"); } // 自定义PropertySource private static class MyPropertySource extends PropertySource<String> { private static final String MY_PROPERTY_SOURCE_KEY = "my.property.source.key"; public MyPropertySource(String name) { super(name); } @Override public Object getProperty(String name) { if (MY_PROPERTY_SOURCE_KEY.equals(name)) { return "myPropertySourceValue"; } return null; } } }在上面的代码中,我们新建了一个名为MyPropertySource的自定义PropertySource,然后在initialize方法中使用environment.getPropertySources().addLast(propertySource)方法将其添加到Spring环境中。
import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.PropertySource; import org.springframework.core.io.support.ResourcePropertySource; import java.io.IOException; /** * @description 注册自定义bean。使用configurableApplicationContext.getBeanFactory().registerSingleton(beanName, bean)方法,可以注册自定义的bean,从而实现更灵活的依赖注入。 */ public class InterveneApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { @Override public void initialize(ConfigurableApplicationContext configurableApplicationContext) { ConfigurableListableBeanFactory beanFactory = configurableApplicationContext.getBeanFactory(); // 注册自定义Bean MyBean myBean = new MyBean(); beanFactory.registerSingleton("myBean", myBean); System.out.println("InterveneApplicationContextInitializer initialize registerSingleton myBean"); } // 堆代码 duidaima.com // 自定义Bean private static class MyBean { private String name = "myBean"; public String getName() { return name; } } }在上面的代码中,我们新建了一个名为MyBean的自定义Bean,然后在initialize方法中使用beanFactory.registerSingleton("myBean", myBean)方法将其注册到Spring应用程序上下文中,"myBean"是注册的bean名称,myBean是实际的类实例对象。需要注意的是,上述代码中的InterveneApplicationContextInitializer需要被注册才能生效。具体如上部分展示,这里不在展示。
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplicationRunListener; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.env.ConfigurableEnvironment; /** * @description SpringApplicationRunListener是Spring Boot的一个事件监听器,用于在应用程序启动和停止时执行一些操作。 * 可能需要自定义SpringApplicationRunListener来执行某些特定操作。 * 下面是一个示例,演示如何扩展SpringApplicationRunListener以添加自定义操作 */ public class IntervenRunListener implements SpringApplicationRunListener { private final SpringApplication application; private final String[] args; public IntervenRunListener(SpringApplication application, String[] args) { this.application = application; this.args = args; } @Override public void starting() { System.out.println("IntervenRunListener starting"); } @Override public void environmentPrepared(ConfigurableEnvironment environment) { System.out.println("IntervenRunListener environmentPrepared"); } @Override public void contextPrepared(ConfigurableApplicationContext context) { System.out.println("IntervenRunListener contextPrepared"); } @Override public void contextLoaded(ConfigurableApplicationContext context) { System.out.println("IntervenRunListener contextLoaded"); } @Override public void started(ConfigurableApplicationContext context) { System.out.println("IntervenRunListener started"); } @Override public void running(ConfigurableApplicationContext context) { System.out.println("IntervenRunListener running"); } @Override public void failed(ConfigurableApplicationContext context, Throwable exception) { System.out.println("IntervenRunListener failed"); } }在上述代码中,我们新建了一个名为IntervenRunListener的自定义SpringApplicationRunListener,并在starting()、environmentPrepared()、contextPrepared()、contextLoaded()、started()、running()和failed()方法中添加了自定义操作。
org.springframework.boot.SpringApplicationRunListener= org.zyf.javabasic.springextend.runext.IntervenRunListener(三)ApplicationRunner扩展
环境检查: 为了确保应用程序能够正常运行,我们需要检查它所在的环境是否满足应用程序的要求。例如,我们可能需要检查数据库是否可用,检查文件系统是否可写等。使用ApplicationRunner,我们可以在应用程序启动时立即执行这些检查,并在应用程序无法正常运行时采取适当的措施,如打印警告或抛出异常。
import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; /** * @description 演示如何使用ApplicationRunner在应用程序启动时加载缓存 */ @Component public class CacheInitiator implements ApplicationRunner { @Override public void run(ApplicationArguments args) throws Exception { System.out.println("CacheInitiator cache deal!"); } }在应用程序启动时,ApplicationRunner接口的run方法将被自动调用,从而将一些初始数据加载到缓存中。当应用程序需要访问缓存时,它们可以立即从缓存中获取数据,而不必等待它们被“懒加载”的时间。这将大大提高应用程序的性能和用户体验。
import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; /** * @description 演示如何使用ApplicationRunner在应用程序启动时执行环境检查 */ @Component public class EnvironmentChecker implements ApplicationRunner { @Override public void run(ApplicationArguments args) throws Exception { // 检查数据库是否可用 System.out.println("EnvironmentChecker DatabaseConnection checkConnection! "); // 检查文件系统是否可写 System.out.println("EnvironmentChecker FileStorage checkWriteAccess! "); } }在应用程序启动时,ApplicationRunner接口的run方法将被自动调用,从而执行环境检查操作。当应用程序无法正常运行时,它们将抛出一个运行时异常,包含适当的错误消息,以帮助我们进行故障排除和修复操作。
import com.google.common.collect.Lists; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; import org.zyf.javabasic.common.User; import java.util.List; /** * @description 演示如何使用CommandLineRunner接口创建一个名为UserImportCommand的命令行工具,用于导入用户数据到应用程序中。 */ @Component public class UserImportCommand implements CommandLineRunner { @Override public void run(String... args) throws Exception { List<User> users = readUserFromFile("fileName"); System.out.println("UserImportCommand readUserFromFile importUsers!"); } // 从数据文件中读取用户信息 private List<User> readUserFromFile(String fileName) { // 省略代码,从文件中读取用户信息,返回一个User对象列表 return Lists.newArrayList(); } }在应用程序启动时,CommandLineRunner接口的run方法将被自动调用,并将命令行参数作为字符串数组传递给run方法。
java -jar myapp.jar user-import users.txt其中,myapp.jar是应用程序运行的jar包,user-import是命令行工具的名称,users.txt是要导入的用户数据文件名。
import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; /** * @description 演示如何使用CommandLineRunner来执行一些自定义启动任务 */ @Component public class StartupTasks implements CommandLineRunner { @Override public void run(String... args) throws Exception { // 加载应用程序配置 System.out.println("StartupTasks configService loadConfig"); // 初始化缓存 System.out.println("StartupTasks cacheService initialize"); } }在应用程序启动时,CommandLineRunner接口的run方法将被自动调用,并且我们的自定义启动任务将会被执行。通过使用CommandLineRunner接口,我们可以执行任何自定义的启动任务,以满足特定的应用程序需求。