Spring-boot实例学习之Simple Command line application

前言

本文将分析spring-boot在git上的一个sample code,一个简单的命令行应用(Simple command line application)的实现。这个例子通过启动main方法,来加载相关配置,并打印一段简单的文字。

实现CommandLineRunner接口并输出数据

当SpringApplication启动后,我们希望执行某些代码,这是可以通过实现ApplicationRunner或CommandLineRunner接口来实现我们的需求。两个接口的工作方式相同,并且都提供了一个run方法,该方法将在SpringApplication.run(…​)完成之后被调用。

为了实现上述功能,我们需要先加添加依赖。

 <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.4.RELEASE</version>
  </parent>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
    </dependency>

当启动main方法,SpringApplication.run(…)运行后,我们会看到helloworld输出。

@SpringBootApplication
public class SampleSimpleApplication implements CommandLineRunner {

  @Override
  public void run(String... args) {
    System.out.println("hello world");
  );

  }

  public static void main(String[] args) throws Exception {
    SpringApplication.run(SampleSimpleApplication.class, args);
  }
}

定义CommandLineRunner调用顺序

当有多个CommandLineRunner的实现时,可以通过实现 Ordered接口来定义调用顺序。代码如下。

import org.springframework.boot.CommandLineRunner;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

@Component
public class HelloCommandLine implements CommandLineRunner,Ordered{

  @Override
  public void run(String... args) throws Exception {
    System.out.println(this.getClass().getName());
  }

  @Override
  public int getOrder() {
    return 11;
  }
}

定义HelloWorldService服务

接着定义HelloWorldService服务,该服务的getHelloMessage方法返回一段文本。这个类中@Value注解,该注解会从属性文件中获取数据作为成员的默认值。@Value(“${name:world}”),从classpath下的application.properties文件中寻找key为name的行,并将其值注入name,如果找不到则用world作为默认值。

@Component
public class HelloWorldService {

  @Value("${name:world}")
  private String name;

  public String getHelloMessage() {
    return "Hello world" + this.name;
  }
}

application.properties文件

name=Phil
sample.name=Andy

接着在启动程序中调用,会看到获取的输出。

@SpringBootApplication
public class SampleSimpleApplication implements CommandLineRunner,Ordered {

  @Autowired
  HelloWorldService helloWorldService;

  @Override
  public void run(String... args) {
    System.out.println(helloWorldService.getHelloMessage());
  }

  @Override
  public int getOrder() {
    return 5;
  }

  public static void main(String[] args) throws Exception {
    SpringApplication.run(SampleSimpleApplication.class, args);
  }
}

属性配置对象SampleConfigurationProperties

SampleConfigurationProperties的作用是,
这里用到了@ConfigurationProperties注解,该注解将properties或者yml配置直接转成对象。该例中的属性配置文件仍为上文的application.properties。详情参考Externalized Configuration

@Component
@ConfigurationProperties(prefix = "sample")
public class SampleConfigurationProperties {
  private String name;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }
}

在启动方法中注入该对象并打印,可以看到输出的配置信息。


@SpringBootApplication
public class SampleSimpleApplication implements CommandLineRunner{

  @Autowired
  HelloWorldService helloWorldService;

  @Autowired
  SampleConfigurationProperties properties;

  @Override
  public void run(String... args) {
    System.out.println(helloWorldService.getHelloMessage());
    System.out.println(properties.getName());
  }

  public static void main(String[] args) throws Exception {
    SpringApplication.run(SampleSimpleApplication.class, args);
  }
}

学习这个Sample遇到的问题

1.产生警告

WARNING : Your ApplicationContext is unlikely to start due to a @ComponentScan of the default package.

因为application.Java 文件不能直接放在main/java文件夹下,必须要建一个包把类放进去,否则会产生该警告。

2.系统启动后看不到输出

开始引入了两个starter pom,一个是web的starter,一个是普通的starter,最后将web的starter以来去掉后程序可以产生输出了。

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>

3.Could not autowire.No beans of HelloWorldService type found.

开始启动类和注入的服务分别在如下的两个包中。

  1. sample.SampleSimpleApplication
  2. service.HelloWorldService

SpringBoot项目的Bean装配默认规则是根据Application类所在的包位置从上往下扫描! “Application类”是指SpringBoot项目入口类。如果Application类所在的包为:com.boot.app,则只会扫描com.boot.app包及其所有子包,如果service或dao所在包不在com.boot.app及其子包下,则不会被扫描! 即, 把Application类放到dao、service所在包的上级,com.boot.Application 知道这一点非常关键,不知道spring文档里有没有给出说明,如果不知道还真是无从解决。

参考:

1.simple command line sample,
https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-simple
2.spring-boot reference guide,
http://docs.spring.io/spring-boot/docs/1.5.4.RELEASE/reference/htmlsingle/#boot-features-command-line-runner

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值