SpringBoot创建非web项目
从开始使用SpringBoot到现在,一直都是在用SpringBoot开发web服务(API服务),其实SpringBoot也支持非web项目。
Spring诞生之初就不是为web项目定制的,SpringBoot无非是在spring核心项目的基础上添加了一些方便开发者使用的组件,所以使用SpringBoot开发非web项目也是可行的。
依赖
创建web项目通常需要使用的依赖是spring-boot-starter-web:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
这个依赖间接引用了tomcat,spring-webmvc,spring-context,json-starter等依赖。这些在非web项目里基本上都用不到,非web项目可以直接使用spring-boot-starter:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
spring-boot-starter间接引用了spring-core、yaml、auto-configure等依赖,已经足够用来创建一个普通的spring项目了。
如果有特殊情况非要使用spring-boot-starter-web依赖来构建非web项目也不是不行,只需要加一些配置来避免启动web容器就行:
spring:
main:
web-application-type: none
或者在启动类中添加web配置并设置为NONE:
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
//SpringApplicationBuilder构造方法参数必须传
SpringApplication application = new SpringApplicationBuilder(MyApplication.class)
.web(WebApplicationType.NONE)
.main(MyApplication.class)
.build(args);
application.run(args);
//阻止程序启动后停止,如果应用内本生存在@Scheduled注解的定时任务,则无需手动阻止程序停止
new Thread(() -> {
synchronized (MyApplication.class) {
try {
MyApplication.class.wait();
} catch (Throwable e) {
}
}
}).start();
}
}
启动
SpringBoot非web项目的启动类定义和web项目并无不同。如下:
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
//阻止程序启动后停止,如果应用内本生存在@Scheduled注解的定时任务,则无需手动阻止程序停止
new Thread(() -> {
synchronized (MyApplication.class) {
try {
MyApplication.class.wait();
} catch (Throwable e) {
}
}
}).start();
}
}
但是执行启动类中的main方法以后呢?如果是web项目,在启动后等待HTTP请求调用就行了。不过这里是非web项目,我们得想办法执行我们定义好的业务逻辑。
因为是非web项目,但是又想一直启动并提供服务,就得自己手动阻止程序停止,如上所示。
接下来按常见的业务逻辑特征分别介绍下:
任务需要定时执行
这种情况需要配置定时任务。SpringBoot对定时任务的支持还算可以。
@EnableScheduling
@Component
public class ScheduleTak {
@Scheduled(cron = "* 0/1 * * * ?")
public void execute() {
System.out.println("-----------> ScheduleTak");
}
}
在某个类的实例注入后就立即执行
通常是需要该类实现InitializingBean接口,并在afterPropertiesSet方法中实现相关的逻辑。如下:
@Service
public class MyService implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("--------->>> start from my service");
}
}
还有一种方式是使用java提供的@PostConstruct注解:
@Service
public class MyService {
@PostConstruct
public void init() {
System.out.println("--------->>> start from my service init method");
}
}
建议最好使用前者。
使用SpringBoot的提供的主动执行接口
SpringBoot提供了两个接口ApplicationRunner和CommandLineRunner来支持主动执行业务逻辑。
比如我们可以直接实现ApplicationRunner接口,并在run方法中添加业务逻辑:
@Component
public class MyRunner1 implements ApplicationRunner {
@Autowired
private MyService myService;
@Override
public void run(ApplicationArguments args) {
System.out.println("--------->>> my runner1 has started");
System.out.println(myService.getId());
}
}
CommandLineRunner接口和ApplicationRunner接口的差别不大。从执行时机还是调用过程上来着,这两者几乎都是一样的。这唯一的区别在于他们提供的run方法的args参数类型上:
- ApplicationRunner的args参数是ApplicationArguments类型,对原始参数做了一层封装;
- CommandLineRunner的args参数是字符串类型,取的是启动类收到的原始参数。
这种差别源于SpringBoot对二者的定位上:
ApplicationRunner适用于启动即执行的场景,只需要读取一次参数信息即可。它的参数通常是“option=value”这种结构的,如:“--foo=bar --foo=baz” 。ApplicationArguments中封装了一些对这种参数进行处理的方法,以便开发使用。
CommandLineRunner从名字上看就是用来做命令行交互用的,所以它这里直接取了原始参数,看一个使用示例:
@Component
public class MyRunner3 implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("Please enter your name:");
try (Scanner scanner = new Scanner(System.in)) {
String name = scanner.nextLine();
System.out.println("Hello " + name + "!");
System.out.println("Bye!");
}
}
}
如果在执行命令行交互之前也需要读取解析传入的参数,那么这里的MyRunner3类完全也可以实现ApplicationRunner接口。二者的差别几乎可以忽略。
在一个应用里面可以有多个ApplicationRunner或CommandLineRunner的实现。要调整两者的实现类之间的执行顺序可以使用@Order注解。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南