一、常见的两个扩展点

1、ApplicationContextInitializer

1.1、作用实现

作用:接口实在Spring容器执行refresh之前的一个回调。

Callback interface for initializing a Spring {@link ConfigurableApplicationContext}

实现:

/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ package org.springframework.context; /**
* Callback interface for initializing a Spring {@link ConfigurableApplicationContext}
* prior to being {@linkplain ConfigurableApplicationContext#refresh() refreshed}.
*
* <p>Typically used within web applications that require some programmatic initialization
* of the application context. For example, registering property sources or activating
* profiles against the {@linkplain ConfigurableApplicationContext#getEnvironment()
* context's environment}. See {@code ContextLoader} and {@code FrameworkServlet} support
* for declaring a "contextInitializerClasses" context-param and init-param, respectively.
*
* <p>{@code ApplicationContextInitializer} processors are encouraged to detect
* whether Spring's {@link org.springframework.core.Ordered Ordered} interface has been
* implemented or if the @{@link org.springframework.core.annotation.Order Order}
* annotation is present and to sort instances accordingly if so prior to invocation.
*
* @author Chris Beams
* @since 3.1
* @see org.springframework.web.context.ContextLoader#customizeContext
* @see org.springframework.web.context.ContextLoader#CONTEXT_INITIALIZER_CLASSES_PARAM
* @see org.springframework.web.servlet.FrameworkServlet#setContextInitializerClasses
* @see org.springframework.web.servlet.FrameworkServlet#applyInitializers
*/
public interface ApplicationContextInitializer<C extends ConfigurableApplicationContext> { /**
* Initialize the given application context.
* @param applicationContext the application to configure
*/
void initialize(C applicationContext); }

1.2、使用步骤

步骤一、写一个类,实现ApplicationContextInitializer接口

步骤二、注册ApplicationContextInitializer接口的实现

注册方式

方式一、SpringApplication

        SpringApplication application = new SpringApplication(App.class);
application.addInitializers(new MyApplicationContextInitializer());

方式二、配置文件

context.initializer.classes=com.lhx.spring.springboot_enableauto.MyApplicationContextInitializer

多个用逗号隔开

方式三、使用spring.factories配置机制,注册监听器

在需要注入的项目包中添加META-INF/spring.factories

org.springframework.context.ApplicationContextInitializer=类名

1.3、使用:

新建一个:MyApplicationContextInitializer

package com.lhx.spring.springboot_enableauto;

import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext; public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { @Override
public void initialize(ConfigurableApplicationContext applicationContext) {
System.out.println("bean count:" + applicationContext.getBeanDefinitionCount());
// ConfigurableListableBeanFactory factory =
// applicationContext.getBeanFactory();
} }

调用

package com.lhx.spring.springboot_enableauto;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication
public class App {
public static void main(String[] args) {
// ConfigurableApplicationContext context = SpringApplication.run(App.class,
// args);
SpringApplication application = new SpringApplication(App.class);
application.addInitializers(new MyApplicationContextInitializer());
ConfigurableApplicationContext context = application.run(args); context.close();
}
}

2、CommandLineRunner、ApplicationRunner【类似开机自启动】

2.1、作用于实现

作用:在spring容器全部初始化完毕,接口在容器启动成功后的最后一步回调

* Interface used to indicate that a bean should <em>run</em> when it is contained within
* a {@link SpringApplication}. Multiple {@link CommandLineRunner} beans can be defined
* within the same application context and can be ordered using the {@link Ordered}
* interface or {@link Order @Order} annotation.

实现

/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ package org.springframework.boot; import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order; /**
* Interface used to indicate that a bean should <em>run</em> when it is contained within
* a {@link SpringApplication}. Multiple {@link CommandLineRunner} beans can be defined
* within the same application context and can be ordered using the {@link Ordered}
* interface or {@link Order @Order} annotation.
* <p>
* If you need access to {@link ApplicationArguments} instead of the raw String array
* consider using {@link ApplicationRunner}.
*
* @author Dave Syer
* @see ApplicationRunner
*/
public interface CommandLineRunner { /**
* Callback used to run the bean.
* @param args incoming main method arguments
* @throws Exception on error
*/
void run(String... args) throws Exception; }

2.2、使用步骤

步骤一、写一个类实现CommandLineRunner接口

步骤二、把该类加入到Spring容器之中,可以通过@Order或Ordered接口控制顺序,注解越小越先执行

2.3、使用

新建一个类ServerSuccessReport实现接口CommandLineRunner

package com.lhx.spring.springboot_enableauto;

import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component; @Component
public class ServerSuccessReport implements CommandLineRunner { @Override
public void run(String... args) throws Exception {
System.out.println("----CommandLineRunner执行-----");
} }

注意同类接口

ApplicationRunner,

void run(ApplicationArguments args) 

只是参数不一样

CommandLineRunner是原始参数,没有任何处理

ApplicationRunner是ApplicationArguments 对象,是对原始参数进一步的封装

3.ApplicationArguments

是对参数(main方法)进一步重载

可以解析--name=value的,可以通过name获取value

package com.lhx.spring.springboot_enableauto;

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(App.class);
ConfigurableApplicationContext context = application.run(args); ApplicationArguments arguments = context.getBean(ApplicationArguments.class);
System.out.println(arguments.getSourceArgs().length);
System.out.println(arguments.getOptionNames());
System.out.println(arguments.getOptionValues("name")); context.close();
}
}

010-Spring Boot 扩展分析-ApplicationContextInitializer、CommandLineRunner、ApplicationRunner的更多相关文章

  1. Spring Boot 扩展点应用之工厂加载机制

    Spring 工厂加载机制,即 Spring Factories Loader,核心逻辑是使用 SpringFactoriesLoader 加载由用户实现的类,并配置在约定好的META-INF/spr ...

  2. Spring Boot 启动载入数据 CommandLineRunner

    实际应用中,我们会有在项目服务启动的时候就去载入一些数据或做一些事情这种需求. 为了解决这种问题.Spring Boot 为我们提供了一个方法.通过实现接口 CommandLineRunner 来实现 ...

  3. spring boot原理分析

    1.分析spring-boot-starter-parent <parent> <groupId>org.springframework.boot</groupId> ...

  4. spring boot原理分析启动依赖中parent帮我们干了什么

    主要内容: 1:分析spring-boot-starter-parent 这个依赖 通过前面几篇文章的学习,我们感受到了spring boot的魅力.最明显的感觉就是pom.xml文件.代码少了很多. ...

  5. spring boot 扩展之AutoConfigurationImportListener

    最近阅读spring boot源码时发现,发现当spring使用ConfigurationClassParser加载使用@Configuration注解类后,会使用AutoConfigurationI ...

  6. Spring Boot 实战与原理分析视频课程

    Spring Boot 实战与原理分析视频课程 链接:https://pan.baidu.com/share/init?surl=PeykcoeqZtd1d9lN9V_F-A 提取码: 关注公众号[G ...

  7. 精尽Spring Boot源码分析 - Condition 接口的扩展

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

  8. Spring Boot 启动原理分析

    https://yq.aliyun.com/articles/6056 转 在spring boot里,很吸引人的一个特性是可以直接把应用打包成为一个jar/war,然后这个jar/war是可以直接启 ...

  9. spring boot应用启动原理分析

    spring boot quick start 在spring boot里,很吸引人的一个特性是可以直接把应用打包成为一个jar/war,然后这个jar/war是可以直接启动的,不需要另外配置一个We ...

随机推荐

  1. IDEA--错误:找不到或无法加载XXXXX--解决方法--创建javafx或其他项目出现的问题

    今天一上午超厂长在学习javafx的时候,总是创建一个然后运行就会出现 出现错误:找不到或无法加载主类 找了二个小时,都说是jdk或者其他环境配置问题 按照那些改了也没用重新创建一个也提示出现错误:找 ...

  2. struts2_对Map进行双层迭代

    转自:struts2_对Map进行双层迭代 //后台数据 public String execute() throws Exception { Map<String, List<Produ ...

  3. <img> 标签的 src 属性

    src属性 加载的时候就会请求 1.servlet生成一个图片 2.你直接输入servlet的连接看一下,就是一个图片,和我们自己发布到服务器的一样. 3.页面加载时,会访问这个servelt连接,自 ...

  4. c++ Socket客户端和服务端示例版本一

    客户端 #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <sys/soc ...

  5. new/delete、malloc/free 的区别

    相同点 1.都可以动态的申请或释放内存 2.存储方式相同,动态申请的内存都存放在堆中,无法自动释放,要调用对应的delete和free   区别 1.new能自行的计算需要分配的空间,malloc需要 ...

  6. [转载]MAC、IP头、TCP头、UDP头帧格式、详解

    原文地址:MAC.IP头.TCP头.UDP头帧格式.详解作者:iTudu 转自:http://zoufengfu168.blog.163.com/blog/static/546105520099133 ...

  7. 四、续绑定SignaIR的用户管理-(添加好友和消息盒子)

    一.聊天消息表(普通消息,申请消息,群聊消息) CREATE TABLE MSG_INFO ( MSG_Id INT PRIMARY KEY AUTO_INCREMENT, -- 消息标识 MSG_T ...

  8. Keepalived高可用服务器案例

    部署Keepalived高可用软件,实现如下: - 使用Keepalived实现web服务器的高可用 - Web服务器IP地址分别为192.168.4.100和192.168.4.200 - Web服 ...

  9. 05java基础

    1.BigInteger和BigDecimal类 package cn.jxufe.java.chapter5.demo01; import java.math.BigInteger; public ...

  10. 2019 计蒜之道 复赛 E. 撑起信息安全“保护伞” (贪心,构造,规律)

    为了给全球小学员打起信息安全"保护伞",VIPKID 还建立了一套立体化的安全防御体系,7 \times 247×24 小时持续安全监控与应急响应等多项联动,具备业界最高级别的数据 ...