欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 宝鼎售后问题提交 | 后台管理


新闻资讯

MENU

软件开发知识

#p#分页标题#e# 创建ApplicationContext private Class? extends Conf

点击: 次  来源:宝鼎软件 时间:2017-07-30

原文出处: 措施员赵鑫

情况

本文基于Spring Boot版本1.3.3, 利用了spring-boot-starter-web。

设置完成后,编写了代码如下:

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

@RestController
public class RootController {

    public static final String PATH_ROOT = "/";

    @RequestMapping(PATH_ROOT)
    public String welcome() {
        return "Welcome!";
    }

}

固然只有几行代码,可是这已经是一个完整的Web措施,当会见url的path部门为”/”时,返回字符串”Welcome!”。

首先是一个很是普通的java措施进口,一个切合约定的静态main要领。在这个main要领中,挪用了SpringApplication的静态run要领,并将Application类工具和main要领的参数args作为参数通报了进去。

然后是一个利用了两个Spring注解的RootController类,我们在main要领中,没有直接利用这个类。

SpringApplication类的静态run要领

以下代码摘自:org.springframework.boot.SpringApplication

public static ConfigurableApplicationContext run(Object source, String... args) {
    return run(new Object[] { source }, args);
}

public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
    return new SpringApplication(sources).run(args);
}

在这个静态要领中,建设SpringApplication工具,并挪用该工具的run要领。

结构SpringApplication工具

以下代码摘自:org.springframework.boot.SpringApplication

public SpringApplication(Object... sources) {
    initialize(sources);
}

private void initialize(Object[] sources) {
    // 为成员变量sources赋值
    if (sources != null && sources.length > 0) {
        this.sources.addAll(Arrays.asList(sources));
    }
    this.webEnvironment = deduceWebEnvironment();
    setInitializers((Collection) getSpringFactoriesInstances(
            ApplicationContextInitializer.class));
    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    this.mainApplicationClass = deduceMainApplicationClass();
}

结构函数中挪用initialize要领,初始化SpringApplication工具的成员变量sources,webEnvironment,initializers,listeners,mainApplicationClass。sources的赋值较量简朴,就是我们传给SpringApplication.run要领的参数。剩下的几个,我们依次来看看是怎么做的。

首先是webEnvironment:

以下代码摘自:org.springframework.boot.SpringApplication

private boolean webEnvironment; 

private static final String[] WEB_ENVIRONMENT_CLASSES = { "javax.servlet.Servlet",
            "org.springframework.web.context.ConfigurableWebApplicationContext" };

private void initialize(Object[] sources) {
    ...
        // 为成员变量webEnvironment赋值
        this.webEnvironment = deduceWebEnvironment();
    ...
}

private boolean deduceWebEnvironment() {
    for (String className : WEB_ENVIRONMENT_CLASSES) {
        if (!ClassUtils.isPresent(className, null)) {
            return false;
        }
    }
    return true;
}

可以看到webEnvironment是一个boolean,该成员变量用来暗示当前应用措施是不是一个Web应用措施。那么怎么抉择当前应用措施是否Web应用措施呢,是通过在classpath中查察是否存在WEB_ENVIRONMENT_CLASSES这个数组中所包括的类,假如存在那么当前措施等于一个Web应用措施,反之则否则。

在本文的例子中webEnvironment的值为true。

然后是initializers:

initializers成员变量,是一个ApplicationContextInitializer范例工具的荟萃。 顾名思义,ApplicationContextInitializer是一个可以用来初始化ApplicationContext的接口。

以下代码摘自:org.springframework.boot.SpringApplication

private List<ApplicationContextInitializer<?>> initializers;

private void initialize(Object[] sources) {
    ...
    // 为成员变量initializers赋值
    setInitializers((Collection) getSpringFactoriesInstances(
            ApplicationContextInitializer.class));
    ...
}

public void setInitializers(
        Collection<? extends ApplicationContextInitializer<?>> initializers) {
    this.initializers = new ArrayList<ApplicationContextInitializer<?>>();
    this.initializers.addAll(initializers);
}

可以看到,要害是挪用getSpringFactoriesInstances(ApplicationContextInitializer.class),来获取ApplicationContextInitializer范例工具的列表。

以下代码摘自:org.springframework.boot.SpringApplication

private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type) {
    return getSpringFactoriesInstances(type, new Class<?>[] {});
}

private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type,
        Class<?>[] parameterTypes, Object... args) {
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    // Use names and ensure unique to protect against duplicates
    Set<String> names = new LinkedHashSet<String>(
            SpringFactoriesLoader.loadFactoryNames(type, classLoader));
    List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
            classLoader, args, names);
    AnnotationAwareOrderComparator.sort(instances);
    return instances;
}