spring boot启动参数及自定义事件配置的几种方法

spring boot启动停止服务的配置

spring boot构建的项目,开发完成后通常配置文件会自动打包在项目中,尽管我们启动项目时可以通过–spring.config.location参数设置读取application.xml或者application.yml文件的位置,但我们还是希望项目启动时可以自动从某些路径读取配置文件。

如果我们用spring boot构建web项目,尽管程序会自动将http服务自动启动,可默认情况下,项目的启动停止只对http服务有效。当我们的项目需要添加其他服务或监听(如tcp服务、webservice服务)时,项目默认的启动停止无法对其他服务生效。

有什么方法能够让我们的spring boot项目在启动停止时,让我们可以指定一些其他操作呢,下面介绍三种实现方法。

main方法中添加监听方法和启动参数

spring boot启动时,我们可以在启动方法SpringApplicationd的run方法执行前,设置启动参数或添加自定义的监听程序。代码案例如下,其中getFilePath()方法是启动类中的私有方法;GramServiceListener类为自己编写的服务监听类(需要实现 org.springframework.context.ApplicationListener接口),可根据实际需要自己编写修改该类。

public static void main(String[] args) throws IOException  {
	Properties properties = new Properties();
	String path = getFilePath();//获取文件路径方法
	//InputStream in = Runner.class.getClassLoader().getResourceAsStream("C:/Users/Administrator/cwht_dir/batchproject/batchConf.properties");
	InputStream in = new FileInputStream(new File(path));
	properties.load(in);
	SpringApplication app = new SpringApplication(Runner.class);
	app.setDefaultProperties(properties);
	app.addListeners(new GramServiceListener());
	app.run(args);
	in.close();
}

GramServiceListener类内容如下

@Override
public void onApplicationEvent(ApplicationEvent event) {
	// TODO Auto-generated method stub
	if (event instanceof ApplicationEnvironmentPreparedEvent){ // 初始化环境变量 
		logger.info("\n\n-======初始化环境变量 ");
	}else if (event instanceof ApplicationPreparedEvent){ // 初始化完成 
		logger.info("\n\n======初始化完成 ");
	} else if (event instanceof ContextRefreshedEvent) { // 应用刷新 }
		logger.info("\n\n=======应用刷新 ");
	}else if (event instanceof ApplicationStartingEvent ) {// 应用已启动完成}
		logger.info("\n\n=======应用已启动完成");
	}else if (event instanceof ContextStartedEvent) { //应用启动,需要在代码动态添加监听器才可捕获 }
		logger.info("\n\n=======应用启动,需要在代码动态添加监听器才可捕获");
	}else if (event instanceof ContextStoppedEvent) { // 应用停止 }
		 logger.info("\n\n=======应用停止");
	}else if(event instanceof ContextClosedEvent) { // 应用关闭 }
		logger.info("\n\n=======应用关闭");
	}
}

实现CommandLineRunner

该方法与对SpringApplication对象添加自定义监听类的效果是一样的。
使用该方法需要我们在spring boot项目的启动类中实现org.springframework.boot.CommandLineRunner接口;同时需要我们在启动类中编写监听方法,并需要为自定义的监听方法添加注解 @EventListener 且方法必须为无返回的公用方法(public void修饰)
以下为案例

public class Application implements CommandLineRunner{
	
	private static Logger logger = LoggerFactory.getLogger(Application.class);

	/**
	 * 描述 : 程序启动入口
	 * @param args
	 * @return void
	 * @throws IOException
	 */
	public static void main(String[] args) throws IOException {
		SpringApplication.run(Application.class,args);
	}

	
	@EventListener
	public void eventApplicationListener(ApplicationEvent applicationEvent) throws Exception{
		if(applicationEvent instanceof ApplicationReadyEvent){
			logger.info("~~~~~~~正在启动服务~~~~~~~~~");
			server.start(port);
		}else if(applicationEvent instanceof ContextClosedEvent){
			logger.info("~~~~~~~正在关闭服务~~~~~~~~~");
			
		}
	}

	@Override
	public void run(String... strings) throws Exception {
		
	}
}

注意:由于CommandLineRunner接口中存在run方法,故启动类中必须重新实现run方法;否则spring boot项目无法正常启动

自定义spring boot的执行器Actuator

该方法需要项目导入Actuator插件(spring-boot-starter-actuator),且由于该方法采用自定义执行器的方式,在spring boot运行的生命流程中,执行我们自己定义的执行器中的相关内容,故可能造成项目运行故障。同时,使用该方式修改,需要编写代码更多,且需要注解的配合或其他插件。故不建议采用该方式实现功能
注意:本文中的执行器基于spring boot 1.5;spring boot 2.0以后已经对执行器进行了升级修改,变化较大,修改时请参考官方文档
我们以执行器插件中停止spring boot服务的执行器ShutdownEndpoint相关的代码为例

1. ShutdownEndpoint

import java.util.Collections;
import java.util.Map;
import org.springframework.beans.BeansException;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;

@ConfigurationProperties(prefix="endpoints.shutdown")
public class ShutdownEndpoint
  extends AbstractEndpoint<Map<String, Object>>
  implements ApplicationContextAware
{
  private static final Map<String, Object> NO_CONTEXT_MESSAGE = Collections.unmodifiableMap(Collections.singletonMap("message", "No context to shutdown."));
  private static final Map<String, Object> SHUTDOWN_MESSAGE = Collections.unmodifiableMap(Collections.singletonMap("message", "Shutting down, bye..."));
  private ConfigurableApplicationContext context;
  
  public ShutdownEndpoint()
  {
    super("shutdown", true, false);
  }
  
  public Map<String, Object> invoke()
  {
    if (this.context == null) {
      return NO_CONTEXT_MESSAGE;
    }
    try
    {
      Thread thread;
      return SHUTDOWN_MESSAGE;
    }
    finally
    {
      Thread thread = new Thread(new Runnable()
      {
        public void run()
        {
          try
          {
            Thread.sleep(500L);
          }
          catch (InterruptedException ex)
          {
            Thread.currentThread().interrupt();
          }
          ShutdownEndpoint.this.context.close();
        }
      });
      thread.setContextClassLoader(getClass().getClassLoader());
      thread.start();
    }
  }
  
  public void setApplicationContext(ApplicationContext context)
    throws BeansException
  {
    if ((context instanceof ConfigurableApplicationContext)) {
      this.context = ((ConfigurableApplicationContext)context);
    }
  }
}

2. ShutdownMvcEndpoint

import java.util.Collections;
import org.springframework.boot.actuate.endpoint.Endpoint;
import org.springframework.boot.actuate.endpoint.ShutdownEndpoint;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@ConfigurationProperties(prefix="endpoints.shutdown")
public class ShutdownMvcEndpoint
 extends EndpointMvcAdapter
{
 public ShutdownMvcEndpoint(ShutdownEndpoint delegate)
 {
   super(delegate);
 }
 
 @PostMapping(produces={"application/vnd.spring-boot.actuator.v1+json", "application/json"})
 @ResponseBody
 public Object invoke()
 {
   if (!getDelegate().isEnabled()) {
     return new ResponseEntity(
       Collections.singletonMap("message", "This endpoint is disabled"), HttpStatus.NOT_FOUND);
   }
   return super.invoke();
 }
}

3. Endpoint的相关配置

在EndpointWebMvcManagementContextConfiguration类中有各种状态检查的配置,其中与停止服务相关的配置如下

import org.springframework.boot.actuate.autoconfigure.EndpointCorsProperties;
import org.springframework.boot.actuate.autoconfigure.HealthMvcEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.ManagementContextConfiguration;
import org.springframework.boot.actuate.condition.ConditionalOnEnabledEndpoint;
import org.springframework.boot.actuate.endpoint.ShutdownEndpoint;
import org.springframework.boot.actuate.endpoint.mvc.ShutdownMvcEndpoint;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

@ManagementContextConfiguration
@EnableConfigurationProperties({HealthMvcEndpointProperties.class, EndpointCorsProperties.class})
public class EndpointWebMvcManagementContextConfiguration
{
  
  @Bean
  @ConditionalOnMissingBean
  @ConditionalOnBean({ShutdownEndpoint.class})
  @ConditionalOnEnabledEndpoint(value="shutdown", enabledByDefault=false)
  public ShutdownMvcEndpoint shutdownMvcEndpoint(ShutdownEndpoint delegate)
  {
    return new ShutdownMvcEndpoint(delegate);
  }
 
}

自定义的执行器可参考shutdown执行器代码,自己添加相应配置即可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: C知道回答:开启 Spring Boot 特性的方式有以下几种: 1. 使用 @EnableAutoConfiguration 注解 2. 使用 @SpringBootApplication 注解 3. 使用 @Configuration 和 @Import 注解手动导入配置类 4. 使用 XML 配置文件手动配置 Spring Boot 特性 ### 回答2: 开启 Spring Boot 特性有以下几种方式: 1. 使用@EnableAutoConfiguration注解:通过在主配置类上添加@EnableAutoConfiguration注解,可以自动开启Spring Boot的自动配置特性。该注解会根据项目中的依赖关系自动配置相应的组件和配置项,简化项目配置工作。 2. 使用@SpringBootApplication注解:@SpringBootApplication是Spring Boot项目的入口注解,它包含了@EnableAutoConfiguration和@Configuration注解。使用@SpringBootApplication注解可以一次性开启Spring Boot的自动配置、组件扫描和配置类的扫描等特性。 3. 使用starter依赖:Spring Boot提供了一系列的starter依赖,每个starter都定义了一组常用的依赖项。通过在项目中引入相应的starter依赖,可以方便地开启特定的功能特性。比如,使用spring-boot-starter-web依赖可以开启Web开发相关的特性。 4. 自定义配置类:在Spring Boot中,我们可以通过编写自定义配置类来开启一些特定的功能。通过在配置类上使用@Configuration注解,我们可以定义一些@Bean的方法配置特定的组件或特性。通过将这个配置类注册为Bean,在应用启动时自动生成相应的组件。 综上所述,使用@EnableAutoConfiguration注解、@SpringBootApplication注解、starter依赖和自定义配置类等方式都可以帮助开启Spring Boot的特性。根据项目需求和实际情况,选择适合的方式来快速搭建和配置Spring Boot应用。 ### 回答3: 开启 Spring Boot 特性有以下几种方式: 1. 使用 @EnableAutoConfiguration 注解:Spring Boot 基于约定优于配置的原则,自动配置了很多常用的特性。通过在主配置类上加上 @EnableAutoConfiguration 注解,可以启用自动配置特性。该注解会根据项目使用的依赖自动配置相关的 Bean,简化了配置过程。 2. 配置文件属性:Spring Boot 通过读取配置文件中的属性来设置特性。可以通过在 application.properties 或 application.yml 配置文件中设置相关属性来开启特性。例如,可以设置 spring.data.mongodb.uri 属性来启用 MongoDB 的支持。 3. 使用 @Conditional 注解:Spring Boot 提供了很多条件注解,利用这些注解可以根据条件来选择性地开启特定的特性。例如,可以使用 @ConditionalOnClass 注解来判断某个类是否在 classpath 中存在,从而决定是否启用某个特性。 4. 自定义配置类:Spring Boot 提供了一个 @Configuration 注解,通过在该注解下定义相关的配置类,可以进行更细粒度的配置。在配置类中可以使用 @Bean 注解配置特性相关的 Bean,从而启用特性。 5. 外部化配置Spring Boot 可以通过外部化配置来灵活地开启和配置特性。可以通过命令行参数、环境变量、属性文件等方式来设置特性相关的配置项。 总之,Spring Boot 提供了多种开启特性的方式,开发人员可以根据项目需求和个人偏好选择适合的方式来启用特性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值