springboot整合netty的多種方式


  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(); } }

看日志:

 

 代表這四種都可以啟動成功,下章接再分析后面三種為什么可以啟動成功


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM