跟我学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); } }
好记性不如烂笔头
浙公网安备 33010602011771号