SpringBoot使用Netty替换tomcat框架

  • 1、创建SpringBoot项目-主启动类如下(NettyHandler是自定义注解,稍后会放出)
@SpringBootApplication
@ComponentScan(includeFilters = @ComponentScan.Filter(NettyHandler.class))
public class DemoMainApplication {

    public static void main(String[] args) {
        new SpringApplicationBuilder(DemoMainApplication.class).web(WebApplicationType.NONE).run(args);
    }
}
  • 2、创建NettyHandler自定义注解
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface  NettyHandler {

    @AliasFor("path")
    String[] value() default {};

    String name() default "";

    RequestMethod[] method() default {};

    @AliasFor("value")
    String[] path() default {};

}
  • 3、创建Netty服务端
@Configuration
public class NettyServer implements ApplicationListener<ApplicationStartedEvent> {

    private static final Logger logger = LoggerFactory.getLogger(NettyServer.class);


    private int port = 8080;


    @Override
    public void onApplicationEvent(@NonNull ApplicationStartedEvent event) {
        ServerBootstrap bootstrap = new ServerBootstrap();
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        ChannelFuture channelFuture = null;
        try {
            bootstrap.group(bossGroup, workerGroup);
            channelFuture =  bootstrap.channel(NioServerSocketChannel.class)
                    .childHandler(new InitServerHandler())
                    .bind(port).syncUninterruptibly().addListener(future -> {
                        String loginfo = "Netty 启动成功!端口=" + port;
                        logger.info(loginfo);
                    });
        }catch (Exception e) {

        } finally {
            channelFuture.channel().closeFuture().addListener(future -> {
                bossGroup.shutdownGracefully();
                workerGroup.shutdownGracefully();
            });
        }

    }
}
  • 4、创建 InitServerHandler(HttpServerHandler 为业务处理类)
public class InitServerHandler extends ChannelInitializer<SocketChannel> {

    @Override
    protected void initChannel(SocketChannel ch) {
        ch.pipeline().addLast("http-decoder",new HttpRequestDecoder());
        ch.pipeline().addLast("http-aggregator", new HttpObjectAggregator(Integer.MAX_VALUE));
        ch.pipeline().addLast("http-encoder", new HttpResponseEncoder());
        ch.pipeline().addLast("http-server", new HttpServerHandler());
    }
}
  • 5、创建业务处理类(setApplicationContext根据业务需求进行改造)
@ChannelHandler.Sharable
@Component
public class HttpServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> implements ApplicationContextAware {


    private static ConcurrentHashMap<String ,HashMap<String, String>> concurrentHashMap = new ConcurrentHashMap<String, HashMap<String, String>>();

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {
		//TODO 处理业务
  		System.out.println("业务处理");
        ctx.writeAndFlush(request).addListener(ChannelFutureListener.CLOSE);

    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

        Map<String, Object> handlers = applicationContext.getBeansWithAnnotation(NettyHandler.class);
        for (Map.Entry<String, Object> entry : handlers.entrySet()) {
            Object handler = entry.getValue();
            for (Method method : handler.getClass().getMethods())
            {
                Annotation[] declaredAnnotations = method.getDeclaredAnnotations();
                for (Annotation ann:declaredAnnotations)
                {
                    if(ann.annotationType().getName().equals(NettyHandler.class.getName()))
                    {
                        String[] value = method.getAnnotation(NettyHandler.class).value();
                        if(value != null)
                        {
                            for (String uri:value)
                            {
                                uri = uri.replace("/","");
                                HashMap<String, String> submap = new HashMap<String, String>();
                                submap.put(method.getName(),handler.getClass().getName());
                                concurrentHashMap.put(uri, submap);
                            }
                        }
                    }
                }
            }
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.fireExceptionCaught(cause);
    }

}

猜你喜欢

转载自blog.csdn.net/xxyybs/article/details/103601472