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