1. 程式人生 > >010-Spring Boot 擴展分析

010-Spring Boot 擴展分析

img erro file ack process multipl rop acc environ

一、常見的兩個擴展點

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); }
View Code

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();
    }

}
View Code

調用

技術分享圖片
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();
    }
}
View Code

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;

}
View Code

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執行-----");
    }

}
View Code

註意同類接口

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 擴展分析