今日,博主遇到一个问题,就是在写项目的时候,用 springboot 启动项目时要启动另外一个 udp 服务,结合我同事的代码,因为他以前是部署在 tomcat 下运行的,但是我不想那么麻烦,想直接 jar 包运行,所以只得重新想办法。现在把这 2 种方式都贴出来,相当于做一个笔记。
tomcat 启动:
/**
* Spring Boot 核心启动类
*/
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@Slf4j
public class CoreApplication extends SpringBootServletInitializer implements CommandLineRunner {@Value("${udp.port}")
private int udpPort;
public static Thread thread;
public static void main(String[] args)
{SpringApplication sa = new SpringApplication(CoreApplication.class);
sa.addListeners(new CloseListener());
sa.run(args);
//SpringApplication.run(Application.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
// 注意这里要指向原先用 main 方法执行的 Application 启动类
builder.listeners(new CloseListener());
return builder.sources(CoreApplication.class);
}
@Override
public void run(String... args) {
// 新开线程避免阻塞 Tomcat 的启动
thread = new Thread(){public void run(){Common.udpProverbServer = new UdpProverbServer();
try {log.info("smartHomeCore UDP"+udpPort+"启动成功");
Common.udpProverbServer.run(udpPort);
//new UdpProverbServer().run(udpPort);
}catch (Exception e){log.error("smartHomeCore UDP 启动失败");
Common.udpProverbServer.stop();
//new UdpProverbServer().stop();
}
}
};
thread.start();}
/**
* 程序停止事件监听器
*/
public static class CloseListener implements ApplicationListener<ContextClosedEvent> {
@Override
public void onApplicationEvent(ContextClosedEvent event) {thread.interrupt();
//Common.udpProverbServer.stop();
log.info("程序和 UDP 服务停止");
}
}
上面的方法就是改装的 SpringApplication,直接在这里面新增一个线程,然后运行相关的代码。
我的做法,就是改变原来需要多开的那个类。
/**
* Netty 实现 UDP 通信核心 - 服务端
*/
@Component
@Slf4j
@Configuration
public class UdpServer implements DisposableBean, Runnable {@Value("${udp.server.port}")
public int udpPort;
public EventLoopGroup group;
private Thread thread;
private volatile boolean someCondition = true;
UdpServer() {this.thread = new Thread(this);
this.thread.start();}
private void udpRun() throws Exception{group = new NioEventLoopGroup();
Bootstrap b = new Bootstrap();
log.info("udp 服务开始启动: 启动端口为 {}",udpPort);
// 由于我们用的是 UDP 协议,所以要用 NioDatagramChannel 来创建
b.group(group).channel(NioDatagramChannel.class)
// 支持广播
.option(ChannelOption.SO_BROADCAST, true)
//ChineseProverbServerHandler 是业务处理类
.handler(new UdpProverbServerHandler());
b.bind(udpPort).sync().channel().closeFuture().await();
}
private void stop() {group.shutdownGracefully();
group.shutdown();}
@Override
public void destroy() throws Exception {someCondition =false;}
@Override
public void run() {
try {while (someCondition){udpRun();
}
} catch (Exception e) {e.printStackTrace();
}
}
public static void main(String [] args) throws Exception{new UdpServer().run();}
就是利用类的构造方法,直接多开一个线程。
正文完