Spring 中容器初始化时调用的接口类

  在日常开发中难免会经常遇到这样的应用场景,在项目初始化时执行指定的代码实现一些功能,或者在项目启动后执行一些代码实现功能。这个时候就需要用到Spring提供的一些接口、注解了。本文都是以SpringBoot为基础。

1.Spring容器启动前执行

   1.1接口类InitializingBean

         直接在代码中实现该接口afterPropertiesSet方法,并在该方法中执行代码。

         值得注意的是  在该接口执行时Spring 容器是还没有初始化完成的。在这里取spring容器中的对象可能会被抛出空指针异常。

@Component
public class TestConfigInitializingBean implements InitializingBean {
	private static final Logger LOGGER = LoggerFactory.getLogger(TestConfigInitializingBean.class);

	@Override
	public void afterPropertiesSet() throws Exception {
		LOGGER.info("--------------------------------------------");
		LOGGER.info("-----正在执行InitializingBean实现类代码-----");
		LOGGER.info("--------------------------------------------");
	}

}

     1.2 注解实现@PostConstruct

        这种方式相对于InitializingBean接口实现要方便一些。直接在需要的方法上添加该注解即可。

        这种方式与上面InitializingBean接口一样都是在spring容器初始化前执行,所有在该注解方法中获取容器内对象可能存在空指针异常


@Component
public class TestPostConstruct {

	private static final Logger LOGGER = LoggerFactory.getLogger(TestPostConstruct.class);

	@PostConstruct
	public void initPostConstruct() {
		LOGGER.info("--------------------------------------------");
		LOGGER.info("-----正在执行@PostConstruct实现类代码-----");
		LOGGER.info("--------------------------------------------");
	}

}

2 Spring容器初始化完成后执行

  2.1 实现监听器 ApplicationListener

      关于这个接口,很多人可能会遇到多次执行该方法。其实这是正常现象,我在执行这段代码时,被重复调用了3次

     通过debug调试观察发现,3次执行参数ApplicationEvent event都是不同的。

     第一次参数内source是AnnotationConfigEmbeddedWebApplicationContext

     第二次参数内source是TomcatEmbeddedServletContainer

     第三次参数内source是SpringApplication

    我个人的理解为springboot web容器加载时触发该方法一次,springboot自带tomcat容器初始化时触发容器一次

     第三次是springApplication  创建并初始化Spring上下文时再次触发该监听

      直接上代码

@Component
public class TestConfigApplicationListener implements ApplicationListener {
	private static final Logger LOGGER = LoggerFactory.getLogger(TestConfigApplicationListener.class);

	@Override
	public void onApplicationEvent(ApplicationEvent event) {
		LOGGER.info("--------------------------------------------");
		LOGGER.info("-----正在执行ApplicationListener实现类代码-----");
		LOGGER.info("--------------------------------------------");
	}

}

    补充: ApplicationEvent该类是一个监听事件抽象类,它下面有很多子类。分别实现不同的事件监听。该监听器的具体执行时间可根据不同的监听类型对象(ApplicationEvent子类)在不同的时间执行 项目启动前、启动后等,具体每个类的监听后面的文章在分析。

    原理:ApplicationContextAware接口提供了publishEvent方法,实现了Observe(观察者)设计模式的传播机制,实现了对bean的传播。通过ApplicationContextAware把系统中所有ApplicationEvent传播给所有的ApplicationListener。

Spring 中容器初始化时调用的接口类_第1张图片

      2.2 实现接口ApplicationRunner

        在代码中实现接口的run方法,并在run方法中编写逻辑代码

       该方法可以通过@order(value= 数字) 来控制执行顺序,顺序是依次从小到大执行

  

@Component
@Order(value = 3)
public class TestConfigApplicationRunner implements ApplicationRunner {
	private static final Logger LOGGER = LoggerFactory.getLogger(TestConfigApplicationRunner.class);

	@Override
	public void run(ApplicationArguments args) throws Exception {
		LOGGER.info("--------------------------------------------");
		LOGGER.info("-----正在执行ApplicationRunner实现类代码-----");
		LOGGER.info("--------------------------------------------");
	}

}

       2.2 实现接口CommandLineRunner

        CommandLineRunner接口的使用方式与ApplicationRunner接口基本相似,不同的只是方法的参数类型,CommandLineRunner的参数是基本类型,而ApplicationRunner是的参数是ApplicationArguments对象,经过封装,用户可对参数进行更多操作

@Component
@Order(value = 2)
public class TestConfigCommandLineRunner implements CommandLineRunner {

	private static final Logger LOGGER = LoggerFactory.getLogger(TestConfigCommandLineRunner.class);

	@Override
	public void run(String... args) throws Exception {
		LOGGER.info("--------------------------------------------");
		LOGGER.info("-----正在执行CommandLineRunner实现类代码-----");
		LOGGER.info("--------------------------------------------");
	}

}

 

代码最终执行结果日志:


  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::       (v1.5.10.RELEASE)

2018-09-05 12:20:08.212  INFO 7140 --- [           main] com.port.test.PortTestApp                : Starting PortTestApp on DESKTOP-R7GPPNQ with PID 7140 (E:\workSpace\learn-project\port-test\target\classes started by zane in E:\workSpace\learn-project\port-test)
2018-09-05 12:20:08.214  INFO 7140 --- [           main] com.port.test.PortTestApp                : No active profile set, falling back to default profiles: default
2018-09-05 12:20:08.255  INFO 7140 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@140e5a13: startup date [Wed Sep 05 12:20:08 CST 2018]; root of context hierarchy
2018-09-05 12:20:09.431  INFO 7140 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2018-09-05 12:20:09.443  INFO 7140 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2018-09-05 12:20:09.445  INFO 7140 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.27
2018-09-05 12:20:09.554  INFO 7140 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2018-09-05 12:20:09.554  INFO 7140 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1301 ms
2018-09-05 12:20:09.681  INFO 7140 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'dispatcherServlet' to [/]
2018-09-05 12:20:09.684  INFO 7140 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-09-05 12:20:09.685  INFO 7140 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-09-05 12:20:09.685  INFO 7140 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-09-05 12:20:09.685  INFO 7140 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2018-09-05 12:20:09.733  INFO 7140 --- [           main] c.p.t.config.TestConfigInitializingBean  : --------------------------------------------
2018-09-05 12:20:09.733  INFO 7140 --- [           main] c.p.t.config.TestConfigInitializingBean  : -----正在执行InitializingBean实现类代码-----
2018-09-05 12:20:09.733  INFO 7140 --- [           main] c.p.t.config.TestConfigInitializingBean  : --------------------------------------------
2018-09-05 12:20:09.736  INFO 7140 --- [           main] com.port.test.config.TestPostConstruct   : --------------------------------------------
2018-09-05 12:20:09.736  INFO 7140 --- [           main] com.port.test.config.TestPostConstruct   : -----正在执行@PostConstruct实现类代码-----
2018-09-05 12:20:09.736  INFO 7140 --- [           main] com.port.test.config.TestPostConstruct   : --------------------------------------------
2018-09-05 12:20:09.969  INFO 7140 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@140e5a13: startup date [Wed Sep 05 12:20:08 CST 2018]; root of context hierarchy
2018-09-05 12:20:10.038  INFO 7140 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2018-09-05 12:20:10.039  INFO 7140 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2018-09-05 12:20:10.066  INFO 7140 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-09-05 12:20:10.066  INFO 7140 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-09-05 12:20:10.098  INFO 7140 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-09-05 12:20:10.220  INFO 7140 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2018-09-05 12:20:10.229  INFO 7140 --- [           main] c.p.t.c.TestConfigApplicationListener    : --------------------------------------------
2018-09-05 12:20:10.230  INFO 7140 --- [           main] c.p.t.c.TestConfigApplicationListener    : -----正在执行ApplicationListener实现类代码-----
2018-09-05 12:20:10.230  INFO 7140 --- [           main] c.p.t.c.TestConfigApplicationListener    : --------------------------------------------
2018-09-05 12:20:10.290  INFO 7140 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2018-09-05 12:20:10.291  INFO 7140 --- [           main] c.p.t.c.TestConfigApplicationListener    : --------------------------------------------
2018-09-05 12:20:10.291  INFO 7140 --- [           main] c.p.t.c.TestConfigApplicationListener    : -----正在执行ApplicationListener实现类代码-----
2018-09-05 12:20:10.291  INFO 7140 --- [           main] c.p.t.c.TestConfigApplicationListener    : --------------------------------------------
2018-09-05 12:20:10.293  INFO 7140 --- [           main] c.p.t.c.TestConfigCommandLineRunner      : --------------------------------------------
2018-09-05 12:20:10.293  INFO 7140 --- [           main] c.p.t.c.TestConfigCommandLineRunner      : -----正在执行CommandLineRunner实现类代码-----
2018-09-05 12:20:10.293  INFO 7140 --- [           main] c.p.t.c.TestConfigCommandLineRunner      : --------------------------------------------
2018-09-05 12:20:10.293  INFO 7140 --- [           main] c.p.t.c.TestConfigApplicationRunner      : --------------------------------------------
2018-09-05 12:20:10.293  INFO 7140 --- [           main] c.p.t.c.TestConfigApplicationRunner      : -----正在执行ApplicationRunner实现类代码-----
2018-09-05 12:20:10.293  INFO 7140 --- [           main] c.p.t.c.TestConfigApplicationRunner      : --------------------------------------------
2018-09-05 12:20:10.294  INFO 7140 --- [           main] c.p.t.c.TestConfigApplicationListener    : --------------------------------------------
2018-09-05 12:20:10.294  INFO 7140 --- [           main] c.p.t.c.TestConfigApplicationListener    : -----正在执行ApplicationListener实现类代码-----
2018-09-05 12:20:10.294  INFO 7140 --- [           main] c.p.t.c.TestConfigApplicationListener    : --------------------------------------------
2018-09-05 12:20:10.295  INFO 7140 --- [           main] com.port.test.PortTestApp                : Started PortTestApp in 2.328 seconds (JVM running for 2.652)

 

 

 

 

 

 

 

 

 

 

 

 

   

 

你可能感兴趣的:(Java,Spring,SpringBoot)