跟我学springboot之(二)项目实战

创建springboot项目

 

package com.lf.web;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

/**
 * Created by LF on 2017/4/11.
 */
@RestController
public class HelloWordController {

    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String hello() {
        return "hello,word";
    }
}

 

启动主程序,打开浏览器访问http://localhost:8080/hello,可以看到页面输出Hello World


如何提前将部分数据加载到Spring容器中:

 1)定义静态常量,随着类的生命周期加载而提前加载;
 2)实现CommandLineRunner接口;容器启动之后,加载实现类的逻辑资源,已达到完成资源初始化的任务;
 3)@PostConstruct;在具体Bean的实例化过程中执行,@PostConstruct注解的方法,会在构造方法之后执行;
     加载顺序为:Constructor > @Autowired > @PostConstruct > 静态方法;
    特点:
      只有一个非静态方法能使用此注解
      被注解的方法不得有任何参数
      被注解的方法返回值必须为void
     被注解方法不得抛出已检查异常
      此方法只会被执行一次
      实现InitializingBean接口;重写afterPropertiesSet()方法;

springboot提供CommandLineRunner.java接口,实现功能的代码放在实现的run方法中加载,并且如果多个类需要加载顺序,则实现类上使用@Order注解,且value值越小则优先级越高。
案例:
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Order(1)
public class RunningRoadOne implements CommandLineRunner {

    @Override
    public void run(String... args) throws Exception {
        System.out.println("初始化需要加载第一类数据");
    }

}
package com.forezp.conf;

import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Order(1)
public class RunningRoadTwo implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("初始化需要加载第二类数据");
    }
}

启动:

 

 源码解析:

public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
     //设置线程启动计时器 stopWatch.start(); ConfigurableApplicationContext context
= null; Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>(); //配置系统属性:默认缺失外部显示屏等允许启动
     configureHeadlessProperty();
//获取并启动事件监听器,如果项目中没有其他监听器,则默认只有EventPublishingRunListener SpringApplicationRunListeners listeners
= getRunListeners(args);
//将事件广播给listeners listeners.starting();
try {
//对于实现ApplicationRunner接口,用户设置ApplicationArguments参数进行封装 ApplicationArguments applicationArguments
= new DefaultApplicationArguments(args); //配置运行环境:激活应用***.yml配置文件
       ConfigurableEnvironment environment
= prepareEnvironment(listeners, applicationArguments); configureIgnoreBeanInfo(environment);
//加载配置的banner(gif,txt...),即控制台图样 Banner printedBanner
= printBanner(environment);
       //创建上下文对象,并实例化 context
= createApplicationContext(); exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[] { ConfigurableApplicationContext.class }, context);
//配置SPring容器 prepareContext(context, environment, listeners, applicationArguments, printedBanner); //刷新Spring上下文,创建bean过程中
       refreshContext(context);
//空方法,子类实现 afterRefresh(context, applicationArguments);
//停止计时器:计算线程启动共用时间 stopWatch.stop();
if (this.logStartupInfo) { new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch); }
        //启动事件监听器 listeners.started(context);
//开始加载资源 callRunners(context, applicationArguments); }
catch (Throwable ex) { handleRunFailure(context, ex, exceptionReporters, listeners); throw new IllegalStateException(ex); } try { listeners.running(context); } catch (Throwable ex) { handleRunFailure(context, ex, exceptionReporters, null); throw new IllegalStateException(ex); } return context; }

 

//资源加载
private
void callRunners(ApplicationContext context, ApplicationArguments args) {
//将实现ApplicationRunner和CommandLineRunner接口的类,存储到集合中 List
<Object> runners = new ArrayList<>(); runners.addAll(context.getBeansOfType(ApplicationRunner.class).values()); runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
     //按照加载先后顺序排序 AnnotationAwareOrderComparator.sort(runners);
for (Object runner : new LinkedHashSet<>(runners)) { if (runner instanceof ApplicationRunner) { callRunner((ApplicationRunner) runner, args); } if (runner instanceof CommandLineRunner) { callRunner((CommandLineRunner) runner, args); } } }

 

callRunner方法
private void callRunner(CommandLineRunner runner, ApplicationArguments args) {
        try {
        //调用各个实现类中的逻辑实现 (runner).run(args.getSourceArgs()); }
catch (Exception ex) { throw new IllegalStateException("Failed to execute CommandLineRunner", ex); } }

 









































 

posted on 2022-08-05 09:29  让代码飞  阅读(235)  评论(0)    收藏  举报

导航

一款免费在线思维导图工具推荐:https://www.processon.com/i/593e9a29e4b0898669edaf7f?full_name=python