netty作為一個高性能的io框架,是非好用的一個技術框架,
Netty 是一個基於NIO的客戶、服務器端編程框架,使用Netty 可以確保你快速和簡單的開發出一個網絡應用,例如實現了某種協議的客戶、
服務端應用。Netty相當於簡化和流線化了網絡應用的編程開發過程,例如:基於TCP和UDP的socket服務開發。
“快速”和“簡單”並不用產生維護性或性能上的問題。Netty 是一個吸收了多種協議(包括FTP、SMTP、HTTP等各種二進制文本協議)的實現經驗,並經過相當精心設計的項目。最終,Netty 成功的找到了一種方式,在保證易於開發的同時還保證了其應用的性能,穩定性和伸縮性
那么如何和springboot這個比較流行的框架進行整合呢?
首先整個項目引入pom
<?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.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.cxy</groupId>
<artifactId>netty</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>netty</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.25.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
handler類是不會改變的
package com.cxy.netty.controller;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;
public class EchoServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg){ ByteBuf in = (ByteBuf) msg; System.out.println("Server received: " + in.toString(CharsetUtil.UTF_8)); ctx.write(in); } @Override public void channelReadComplete(ChannelHandlerContext ctx){ ctx.writeAndFlush(ChannelFutureListener.CLOSE); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause){ cause.printStackTrace(); ctx.close(); } }
這個handler是我從官網上copy下來的
方式一:注解@PostConstruct
package com.cxy.netty.controller;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.net.InetSocketAddress;
@Component
public class NettyServer { /*private int port =8080; public int getPort() { return port; } public void setPort(int port) { this.port = port; } public NettyServer(int port) { this.port = port; }*/ @PostConstruct public void start() throws Exception { System.out.println("啟動記載netty"); EventLoopGroup boss = new NioEventLoopGroup(); EventLoopGroup work = new NioEventLoopGroup(); ServerBootstrap b = new ServerBootstrap(); b.group(boss,work) .channel(NioServerSocketChannel.class) .localAddress(new InetSocketAddress(8082)) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new EchoServerHandler()); } }); System.out.println("啟動加載netty2"); ChannelFuture channelFuturef = b.bind().sync(); if (channelFuturef.isSuccess()){ System.out.println("啟動成功"); } } }
點擊啟動:
看日志:
說明已經啟動
那么這個注解為什么這么神奇呢:
大概的意思,大家看下,意思就是這個方法會隨着類的加載而加載,初始化加載的意思:
@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PostConstruct { }
方式二:利用監聽器啟動:
package com.cxy.netty.controller;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* 系統初始化監聽器
* @author Administrator
*
*/
public class InitListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { NettyServer nettyServer = new NettyServer(8081); try { nettyServer.start(); } catch (Exception e) { e.printStackTrace(); } } @Override public void contextDestroyed(ServletContextEvent sce) { } }
啟動類:
package com.cxy.netty;
import com.cxy.netty.controller.InitListener;
import com.cxy.netty.controller.NettyServer;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class NettyApplication { /** * 注冊監聽器 * @return */ @SuppressWarnings({ "rawtypes", "unchecked" }) @Bean public ServletListenerRegistrationBean servletListenerRegistrationBean() { ServletListenerRegistrationBean servletListenerRegistrationBean = new ServletListenerRegistrationBean(); servletListenerRegistrationBean.setListener(new InitListener()); return servletListenerRegistrationBean; } public static void main(String[] args) { SpringApplication.run(NettyApplication.class, args); } }
看日志:
三 :利用 ApplicationListener 上下文監聽器
package com.cxy.netty.controller;
import com.cxy.netty.controller.NettyServer;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.stereotype.Component; @Component public class NettyBooter implements ApplicationListener<ContextRefreshedEvent> { @Override public void onApplicationEvent(ContextRefreshedEvent event) { NettyServer nettyServer = new NettyServer(8081); try { nettyServer.start(); } catch (Exception e) { e.printStackTrace(); } } }
啟動類:
package com.cxy.netty;
import com.cxy.netty.controller.NettyServer;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class NettyApplication { /** * 注冊監聽器 * @return */ /* @SuppressWarnings({ "rawtypes", "unchecked" }) @Bean public ServletListenerRegistrationBean servletListenerRegistrationBean() { ServletListenerRegistrationBean servletListenerRegistrationBean = new ServletListenerRegistrationBean(); servletListenerRegistrationBean.setListener(new InitListener()); return servletListenerRegistrationBean; }*/ public static void main(String[] args) { SpringApplication.run(NettyApplication.class, args); } }
看啟動日志:
四:commiandLinerunner啟動
package com.cxy.netty;
import com.cxy.netty.controller.NettyServer;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
/*
@SpringBootApplication
public class NettyApplication {
*/
/**
* 注冊監聽器
* @return
*//*
*/
/* @SuppressWarnings({ "rawtypes", "unchecked" })
@Bean
public ServletListenerRegistrationBean servletListenerRegistrationBean() {
ServletListenerRegistrationBean servletListenerRegistrationBean =
new ServletListenerRegistrationBean();
servletListenerRegistrationBean.setListener(new InitListener());
return servletListenerRegistrationBean;
}*//*
public static void main(String[] args) {
SpringApplication.run(NettyApplication.class, args);
}
}
*/ @SpringBootApplication public class NettyApplication implements CommandLineRunner { public static void main(String[] args) { SpringApplication.run(NettyApplication.class, args); } @Override public void run(String... args) throws Exception { NettyServer echoServer = new NettyServer(8083); echoServer.start(); } }
看日志:
代表這四種都可以啟動成功,下章接再分析后面三種為什么可以啟動成功