有时候我们在项目里有这样的需求,不在pom文件指定主类,而是在启动时指定主类,这个我研究了半天,发现可用实现,记录一下
有这么几个点需要关注:
1.pom打包的配置
要么指定mainClass,要不就把layout设定为ZIP,里面的原理有机会再深入了解
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals> <goal>repackage</goal> </goals> <configuration> <!--如下配置,使Spring Boot使用PropertiesLauncher,可以實現在命令行指定啟動類--> <layout>ZIP</layout> </configuration> </execution> </executions> </plugin> </plugins> </build>
2.代码中的配置
2.1 首先,原来的启动类还是要有的
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class,args); } }
2.2 其次,在其他的包再建一个自定义的启动类
@ComponentScan(value = "org.example") public class ZKMasterConfig { @Autowired private ZKMasterClient zkMasterClient; public static void main(String[] args) { Thread.currentThread().setName("ZKMasterConfig"); new SpringApplicationBuilder(ZKMasterConfig.class).web(WebApplicationType.NONE).run(args); } }
2.3 特别指定了启动类,肯定是想执行特别的代码,经我测试,在这个启动类里@PostConstruct注解是不能生效的,想要初始化方法,还需要实现ApplicationRunner接口
@Component public class ZKMasterClient implements ApplicationRunner{ private final Logger logger = LoggerFactory.getLogger(ZKMasterClient.class); @Autowired private CuratorFramework zkClient; @Override public void run(ApplicationArguments args) throws Exception{ System.out.println("**************i'm ZKMasterClient.run()***************"); } }
这里有个问题,不实现接口就无法执行方法,实现了方法但其他实现了这个接口的类run方法都会执行,怎么只执行自己想要初始化的run呢?
3.java -jar执行时的配置
mvn clean install -Dmaven.test.skip java -jar distribute-sync-1.0-SNAPSHOT.jar -Dloader.main=org.example.server.ZKMasterConfig
指定启动类实现了,但个性化初始化并没有实现