• springboot整合netty,多种启动netty的方式,展现bean得多种启动方法


    首先讲解下,spring中初始化加载问题:

    很多时候,我们自己写的线程池,还有bean对象,还有其他的服务类,都可以通过,相关注解进行交给spring去管理,那么我们如何让nettyserver初始化加载呢:

    在springBean的生命周期中有 

    引入pom.xml

    <?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>

    1   InitializingBean  在系统初始化之后加载

    
    
    package com.cxy.netty.controller;

    import org.springframework.beans.factory.InitializingBean;
    import org.springframework.stereotype.Controller;

    @Controller
    public class DemoController implements InitializingBean {

    @Override
    public void afterPropertiesSet() throws Exception {
    System.out.println("系统加载");
    }
    }
     

    我们可以看下日志:

    "C:Program FilesJavajdk1.8.0_191injava.exe" -XX:TieredStopAtLevel=1 -noverify -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9135 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=localhost -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true "-javaagent:D:Program FilesJetBrainsideaIU-2018.1.2.winlibidea_rt.jar=9136:D:Program FilesJetBrainsideaIU-2018.1.2.winin" -Dfile.encoding=UTF-8 -classpath "C:Program FilesJavajdk1.8.0_191jrelibcharsets.jar;C:Program FilesJavajdk1.8.0_191jrelibdeploy.jar;C:Program FilesJavajdk1.8.0_191jrelibextaccess-bridge-64.jar;C:Program FilesJavajdk1.8.0_191jrelibextcldrdata.jar;C:Program FilesJavajdk1.8.0_191jrelibextdnsns.jar;C:Program FilesJavajdk1.8.0_191jrelibextjaccess.jar;C:Program FilesJavajdk1.8.0_191jrelibextjfxrt.jar;C:Program FilesJavajdk1.8.0_191jrelibextlocaledata.jar;C:Program FilesJavajdk1.8.0_191jrelibext
    ashorn.jar;C:Program FilesJavajdk1.8.0_191jrelibextsunec.jar;C:Program FilesJavajdk1.8.0_191jrelibextsunjce_provider.jar;C:Program FilesJavajdk1.8.0_191jrelibextsunmscapi.jar;C:Program FilesJavajdk1.8.0_191jrelibextsunpkcs11.jar;C:Program FilesJavajdk1.8.0_191jrelibextzipfs.jar;C:Program FilesJavajdk1.8.0_191jrelibjavaws.jar;C:Program FilesJavajdk1.8.0_191jrelibjce.jar;C:Program FilesJavajdk1.8.0_191jrelibjfr.jar;C:Program FilesJavajdk1.8.0_191jrelibjfxswt.jar;C:Program FilesJavajdk1.8.0_191jrelibjsse.jar;C:Program FilesJavajdk1.8.0_191jrelibmanagement-agent.jar;C:Program FilesJavajdk1.8.0_191jrelibplugin.jar;C:Program FilesJavajdk1.8.0_191jrelib
    esources.jar;C:Program FilesJavajdk1.8.0_191jrelib
    t.jar;D:工作idea
    etty	argetclasses;D:javamavenorgspringframeworkootspring-boot-starter-web2.2.1.RELEASEspring-boot-starter-web-2.2.1.RELEASE.jar;D:javamavenorgspringframeworkootspring-boot-starter2.2.1.RELEASEspring-boot-starter-2.2.1.RELEASE.jar;D:javamavenorgspringframeworkootspring-boot2.2.1.RELEASEspring-boot-2.2.1.RELEASE.jar;D:javamavenorgspringframeworkootspring-boot-autoconfigure2.2.1.RELEASEspring-boot-autoconfigure-2.2.1.RELEASE.jar;D:javamavenorgspringframeworkootspring-boot-starter-logging2.2.1.RELEASEspring-boot-starter-logging-2.2.1.RELEASE.jar;D:javamavenchqoslogbacklogback-classic1.2.3logback-classic-1.2.3.jar;D:javamavenchqoslogbacklogback-core1.2.3logback-core-1.2.3.jar;D:javamavenorgapachelogginglog4jlog4j-to-slf4j2.12.1log4j-to-slf4j-2.12.1.jar;D:javamavenorgapachelogginglog4jlog4j-api2.12.1log4j-api-2.12.1.jar;D:javamavenorgslf4jjul-to-slf4j1.7.29jul-to-slf4j-1.7.29.jar;D:javamavenjakartaannotationjakarta.annotation-api1.3.5jakarta.annotation-api-1.3.5.jar;D:javamavenorgyamlsnakeyaml1.25snakeyaml-1.25.jar;D:javamavenorgspringframeworkootspring-boot-starter-json2.2.1.RELEASEspring-boot-starter-json-2.2.1.RELEASE.jar;D:javamavencomfasterxmljacksoncorejackson-databind2.10.0jackson-databind-2.10.0.jar;D:javamavencomfasterxmljacksoncorejackson-annotations2.10.0jackson-annotations-2.10.0.jar;D:javamavencomfasterxmljacksoncorejackson-core2.10.0jackson-core-2.10.0.jar;D:javamavencomfasterxmljacksondatatypejackson-datatype-jdk82.10.0jackson-datatype-jdk8-2.10.0.jar;D:javamavencomfasterxmljacksondatatypejackson-datatype-jsr3102.10.0jackson-datatype-jsr310-2.10.0.jar;D:javamavencomfasterxmljacksonmodulejackson-module-parameter-names2.10.0jackson-module-parameter-names-2.10.0.jar;D:javamavenorgspringframeworkootspring-boot-starter-tomcat2.2.1.RELEASEspring-boot-starter-tomcat-2.2.1.RELEASE.jar;D:javamavenorgapache	omcatembed	omcat-embed-core9.0.27	omcat-embed-core-9.0.27.jar;D:javamavenorgapache	omcatembed	omcat-embed-el9.0.27	omcat-embed-el-9.0.27.jar;D:javamavenorgapache	omcatembed	omcat-embed-websocket9.0.27	omcat-embed-websocket-9.0.27.jar;D:javamavenorgspringframeworkootspring-boot-starter-validation2.2.1.RELEASEspring-boot-starter-validation-2.2.1.RELEASE.jar;D:javamavenjakartavalidationjakarta.validation-api2.0.1jakarta.validation-api-2.0.1.jar;D:javamavenorghibernatevalidatorhibernate-validator6.0.18.Finalhibernate-validator-6.0.18.Final.jar;D:javamavenorgjbossloggingjboss-logging3.4.1.Finaljboss-logging-3.4.1.Final.jar;D:javamavencomfasterxmlclassmate1.5.1classmate-1.5.1.jar;D:javamavenorgspringframeworkspring-web5.2.1.RELEASEspring-web-5.2.1.RELEASE.jar;D:javamavenorgspringframeworkspring-beans5.2.1.RELEASEspring-beans-5.2.1.RELEASE.jar;D:javamavenorgspringframeworkspring-webmvc5.2.1.RELEASEspring-webmvc-5.2.1.RELEASE.jar;D:javamavenorgspringframeworkspring-aop5.2.1.RELEASEspring-aop-5.2.1.RELEASE.jar;D:javamavenorgspringframeworkspring-context5.2.1.RELEASEspring-context-5.2.1.RELEASE.jar;D:javamavenorgspringframeworkspring-expression5.2.1.RELEASEspring-expression-5.2.1.RELEASE.jar;D:javamavenio
    etty
    etty-all4.1.25.Final
    etty-all-4.1.25.Final.jar;D:javamavenorgslf4jslf4j-api1.7.29slf4j-api-1.7.29.jar;D:javamavenorgspringframeworkspring-core5.2.1.RELEASEspring-core-5.2.1.RELEASE.jar;D:javamavenorgspringframeworkspring-jcl5.2.1.RELEASEspring-jcl-5.2.1.RELEASE.jar" com.cxy.netty.NettyApplication
    
      .   ____          _            __ _ _
     /\ / ___'_ __ _ _(_)_ __  __ _    
    ( ( )\___ | '_ | '_| | '_ / _` |    
     \/  ___)| |_)| | | | | || (_| |  ) ) ) )
      '  |____| .__|_| |_|_| |_\__, | / / / /
     =========|_|==============|___/=/_/_/_/
     :: Spring Boot ::        (v2.2.1.RELEASE)
    
    2019-11-23 18:20:49.749  INFO 38380 --- [           main] com.cxy.netty.NettyApplication           : Starting NettyApplication on LAPTOP-MEIVCU3E with PID 38380 (started by cxy in D:工作idea
    etty)
    2019-11-23 18:20:49.752  INFO 38380 --- [           main] com.cxy.netty.NettyApplication           : No active profile set, falling back to default profiles: default
    2019-11-23 18:20:50.606  INFO 38380 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
    2019-11-23 18:20:50.623  INFO 38380 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
    2019-11-23 18:20:50.623  INFO 38380 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.27]
    2019-11-23 18:20:50.736  INFO 38380 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
    2019-11-23 18:20:50.737  INFO 38380 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 947 ms
    系统加载
    2019-11-23 18:20:50.894  INFO 38380 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
    2019-11-23 18:20:51.029  INFO 38380 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
    2019-11-23 18:20:51.032  INFO 38380 --- [           main] com.cxy.netty.NettyApplication           : Started NettyApplication in 1.689 seconds (JVM running for 4.137)

    打印出了系统加载,这个适合有时候系统停机导致内存中的数据会有少部分丢失,必须要在重启之后才调用相关服务才可以调用,才可以加载缓存,那么这个方法可以很有效的加载在jvm内存的数据

    2  注解@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 =8082;
        EventLoopGroup boss = new NioEventLoopGroup();
        EventLoopGroup work = new NioEventLoopGroup();
    
        @PostConstruct
        public void start() throws Exception {
            System.out.println("启动记载netty");
            ServerBootstrap b = new ServerBootstrap();
            b.group(boss,work)
                    .channel(NioServerSocketChannel.class)
                    .localAddress(new InetSocketAddress(port))
                    .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("启动成功");
            }
    
    
        }
    
        @PreDestroy
       private void destory() throws Exception{
            boss.shutdownGracefully();
            work.shutdownGracefully();
            System.out.println("关闭server");
            }
    }

    启动类:

    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 {
       
        public static void main(String[] args) {
            SpringApplication.run(NettyApplication.class, args);
        }
    
    }

    看打印日志:

     从这里代码又可以应征笔者之前说的,netty的使用只需要自己写好那个助手类就可以了;

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

     @PostConstruct  这个注解,到底是怎么样著有这么神奇的功效呢:

    /**
     * The PostConstruct annotation is used on a method that needs to be executed
     * after dependency injection is done to perform any initialization. This
     * method MUST be invoked before the class is put into service. This
     * annotation MUST be supported on all classes that support dependency
     * injection. The method annotated with PostConstruct MUST be invoked even
     * if the class does not request any resources to be injected. Only one
     * method can be annotated with this annotation. The method on which the
     * PostConstruct annotation is applied MUST fulfill all of the following
     * criteria:

    看到,表示,某个方法需要初始化的时候,可以使用这个注解:

     是作用到方法上面的,使用这个整合时候,需要注意问题,就是,我们需要将整个类交给spring去管理,这样,才可以进行初始化,这个类是在spring的包中,所以需要整合必须要用这个二注解。

    3 基础类实现 CommandLineRunner 

    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;
    
    @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(8081);
            echoServer.start();
        }
    }
    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;
    
    public class NettyServer {
        private  int port;
    
        public int getPort() {
            return port;
        }
    
        public void setPort(int port) {
            this.port = port;
        }
    
        public NettyServer(int port) {
            this.port = port;
        }
    
        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(port))
                    .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("启动成功");
            }
    
    
        }
    
    }

    给他初始化的时候,添加启动方法,

    看启动日志:

     注意事项,在nettyServer上不要加component注解

    4 利用 ApplicationListener  上下文监听器

    package com.cxy.netty;
    
    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;
    
    @SpringBootApplication
    public class NettyApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(NettyApplication.class, args);
        }
    
    }

    看启动日志:

     可以看server也启动了。

    5  利用监听器启动:

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

    看日志:

  • 相关阅读:
    base64是什么东东,base64 图片显示,在线编辑器
    中文字符 与 十六进制Unicode编码 相互转换
    全面理解Python中self的用法
    Python之使用元类MetaClass
    Python之MySQL数据库连接驱动aiomysql的使用
    Python实战网站开发:Day2编写Web App骨架
    Python实战网站开发:Day3编写ORM
    Python之MySQL数据库连接驱动pymysql的使用
    【CV基础】为什么一些深度学习的图像预处理使用mean=[0.485, 0.456, 0.406] and std=[0.229, 0.224, 0.225]来正则化?
    与人合作创业是一门大艺术(转)
  • 原文地址:https://www.cnblogs.com/xiufengchen/p/11919341.html
Copyright © 2020-2023  润新知