Springboot 如何打包成可执行jar文件,并在jar文件启动时自动执行指定方法
创建一个maven项目准备工作。
首先得配置好jdk与maven的环境。
下载路径为
JDK,下载地址:(http://www.oracle.com/technetwork/java/javase/downloads/index.html)
Maven 下载地址:(http://maven.apache.org/download.cgi)
具体配置流程可以参考:(https://www.runoob.com/maven/maven-setup.html)
添加依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.15</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
添加启动页
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
注意:@springBootApplication最好放在最外层避免启动时有遗漏的bean没有被注入spring容器中
@SpringBootApplication = (默认属性)@Configuration + @EnableAutoConfiguration + @ComponentScan。
添加service与dao层
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.dao.TaskBatMapper;
import com.example.entity.PortalPipelineVOImpl;
@Service
public class TaskBatServiceImpl {
@Autowired
TaskBatMapper restmapper;
public List<PortalPipelineVOImpl> find(){
return restmapper.find();
}
}
dao层的mapper接口
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import com.example.entity.PortalPipelineVOImpl;
@Mapper
public interface TaskBatMapper {
@Select("select pipeline_id,project_description from portal_pipeline")
public List<PortalPipelineVOImpl> find();
}
实体类
public class PortalPipelineVOImpl {
private String id;
private String pipelineId;
private String projectDescription;
public String getId(){
return id;
public void setId(String id){
this.id = id;
}
public String getPipelineId(){
return pipelineId;
}
public void setPipelineId(String pipelineId){
this.pipelineId = pipelineId;
}
public String getProjectDescription(){
return projectDescription;
}
public void setProjectDescription(String projectDescription){
this.projectDescription = projectDescription;
}
}
配置文件需要配置数据源
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.max-idle=10
spring.datasource.max-wait=10000
spring.datasource.min-idle=5
spring.datasource.initial-size=5
由于我这边的实体类与数据库存放字段不同多了_,所以需要配置驼峰
mybatis.configuration.mapUnderscoreToCamelCase=true
mapper.mappers=com.example.dao.TaskBatMapper
mapper.identity=MYSQL
这样配置完成后大致上的流程就可以跑通了.
接下来就是进入业务了
因为客户需求需要我这边写一个maven项目并打包成一个可执行的jar文件,再配合.bat文件提供给客户,然后客户可以通过.bat文件拿到指定数据库表中的数据并经过java逻辑编辑成的excel或者csv文件。
本来说点击一次启动一次项目,就可以在启动时执行特定的方法生成excel/csv文件,当时就想到有两种方法,一种是方法重写ApplicationRunner接口的run方法,一种是使用quratz定时任务。
ApplicationRunner方式
ApplicationRunner接口的执行时机为容器启动完成的时候,是在项目完成前启动。像我这个需求就不适应了,因为我这需求需要访问数据库并进行操作,在maven install中得先编译一次再打包,但是我这边本地数据库与生产数据库不同,并且我这边是连接不上生产数据库,使用本地数据库是没问题的但是切换成生产数据库就不行了,使用命令 mvn clean package也没用也逃避不了得先执行实现接口的run方法,就会出现这样的问题。
当然你可以先用自己本地的数据库打包出jar文件,然后通过其他方式修改配置文件中数据源的信息,理论上好像是行得通,但是我这边没有具体的操作,有兴趣的小伙伴可以试试。
quartz方式
定时任务是在项目启动后才运行
先添加定时任务的依赖
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
由于这边不太熟悉定时任务注解,所以这边还是打算用一个xml文件配置相关信息。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<!-- 定时器工作调度的bean class后指定匹配的定时任务类-->
<bean id="quartDemo" class="com.example.action.QuartzDemo" />
<!-- job的配置开始 -->
<bean id="quartDemoDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="quartDemo" />
</property>
<property name="targetMethod">
<value>work</value>
</property>
</bean>
<!-- 调度的配置开始 -->
<bean id="crontestJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail">
<ref bean="quartDemoDetail" />
</property>
<property name="cronExpression">
<value>0 0 14 * * ?</value>
</property>
</bean>
<!-- 启动触发器的配置开始 -->
<bean name="startQuertz" lazy-init="false" autowire="no"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="crontestJobTrigger" />
</list>
</property>
</bean>
</beans>
添加configClass类进行加载xml文件。
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
@Configuration
@ImportResource(locations={"classpath:applicationContext-quartz.xml"})
public class ConfigClass {
}
需要在项目启动时就加载一次配置
<!-- 配置项目启动后任务就执行一次 -->
<bean id="rsh_simpleTrigger1" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<property name="jobDetail" ref="quartDemoDetail" />
<property name="startDelay" value="500" />
<property name="repeatInterval" value="0" />
<property name="repeatCount" value="0" />
</bean>
<!-- 启动触发器的配置开始 -->
<bean name="startQuertz" lazy-init="false" autowire="no"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<!--新增 start-->
<ref bean="rsh_simpleTrigger1" />
<!--end-->
<ref bean="crontestJobTrigger" />
</list>
</property>
</bean>
如果说只需要执行一次的话并不需要周期性的执行可以将配置文件中id为crontestJobTrigger的bean与下面触发器绑定的bean删除即可。
具体逻辑我就不贴代码出来了,跑一下的结果,是没有没问题的。
然后打包,我一开始发现我的eclipse 项目 右键run as中没有maven package,但是有maven clean ,maven install,这就很离谱了,所以找到文件目录下,启动cmd 输入mvn clean package,运行结果。
发现也是没有问题的。
总算是大功告成了。
将jar包在普通机上进行测试,由于普通机上没有java 的开发环境所以不能直接使用java -jar jarfile.jar,得配合jdk一同使用,具体命令为 jdkpath\bin\java.exe -jar jarfile.jar启动。
最后贴下项目路径吧。
总结
第一次写博客,有很多不足的地方还是希望小伙伴们提出来一同探讨一同学习。
也感谢该博主的quartz分享 https://my.oschina.net/fwe/blog/1600349