Netty 4.1.22 Jar 下载
NettyServer
抽象成公共的服务类、子服务类只需继承、并传入端口和处理类
/**
 * NettyServer 启动服务
 *
 * @author MENG
 * @version 2018/3/20
 * @see
 */
public abstract class NettyServer
{
    Logger logger = LoggerFactory.getLogger(NettyServer.class);
    /**
     *  端口
     */
    private int port;
    /**
     * 通道初始化类
     */
    private ChannelInitializer channelInitializer;
    public NettyServer(int port,ChannelInitializer channelInitializer)
    {
        this.port = port;
        this.channelInitializer = channelInitializer;
    }
    /**
     * 启动服务
     *
     */
    public void start()
    {
        /**
         * NioEventLoopGroup 是用来处理I/O操作的多线程事件循环器
         *
         * 第一个经常被叫做‘boss’,用来接收进来的连接
         *
         * 第二个经常被叫做‘worker’,用来处理已经被接收的连接
         *
         *  一旦‘boss’接收到连接,就会把连接信息注册到‘worker’上
         *
         * worker的EventLoopGroup默认的线程数是CPU核数的二倍。
         *
         * NettyRuntime.availableProcessors() * 2 = Runtime.getRuntime().availableProcessors() * 2
         */
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try
        {
            /**
             * ServerBootstrap 是一个启动NIO服务的辅助启动类 你可以在这个服务中直接使用Channel
             *
             */
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            /**
             * 这一步是必须的,如果没有设置group将会报java.lang.IllegalStateException: group not set异常
             *
             */
            serverBootstrap = serverBootstrap.group(bossGroup, workerGroup);
            /***
             * ServerSocketChannel以NIO的selector为基础进行实现的,用来接收新的连接这里告诉Channel如何获取新的连接.
             *
             */
            serverBootstrap = serverBootstrap.channel(NioServerSocketChannel.class);
            /**
             * option是设置 bossGroup
             *
             * childOption是设置workerGroup
             *
             * 使用对象池,重用缓冲区
             */
            serverBootstrap = serverBootstrap.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
            serverBootstrap = serverBootstrap.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
            /**
             * 设置 通道 处理类
             *
             */
            serverBootstrap = serverBootstrap.childHandler(channelInitializer);
            ChannelFuture f = serverBootstrap.bind(port).sync();
            logger.info("Start netty server-port : {} ...",port);
            //等待服务器监听端口关闭
            f.channel().closeFuture().sync();
        }
        catch (InterruptedException e)
        {
            logger.error("Netty 绑定端口错误",e);
        }
        finally
        {
            // Shut down all event loops to terminate all threads.
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}
PaintOfSaleServer
NettyServer 子类
/**
 * POS 服务端  echo:有响应的服务
 *
 * @author MENG
 * @version 2018/3/19
 * @see
 */
@PublishNettyServer
public class PointOfSaleServer extends NettyServer
{
    public PointOfSaleServer() throws IOException
    {
        //传入 端口 和 通道
        super(Integer.parseInt(Utils.getNettyPropsValByKey("pos.server.port")), new ChannelInitializer<SocketChannel>() {
            @Override
            public void initChannel(SocketChannel ch) throws Exception
            {
                // 属于ChannelOutboundHandler,逆序执行
                ch.pipeline().addLast(new PointOfSaleEncoder());
                // 属于ChannelInboundHandler,按照顺序执行
                ch.pipeline().addLast(new PointOfSaleDecoder());
                ch.pipeline().addLast(new PointOfSaleHandler());
            }
        });
    }
}
@PublishNettyServer
自定义注解用于发布Netty服务
/**
 * 发布netty Server对象注解
 *
 * @author MENG
 * @version 2018/03/20
 * @see
 */
@Target({ ElementType.TYPE})//接口、类、枚举、注解
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PublishNettyServer
{
    String description() default "";
}
Spring boot 2.0 整合 Redis 配置
/**
 * redis 配置类
 *
 * @EnableRedisHttpSession 开启spring session支持
 *
 * 过期时间:maxInactiveIntervalInSeconds 秒
 *
 * @author MENG
 * @version 2017/12/24
 * @see
 */
@Configuration
public class RedisConfig extends CachingConfigurerSupport
{
    /**
     *
     * spring提供两个类操作Redis RedisTemplate(操作对象) StringRedisTemplate(操作String)
     *
     * @param factory
     * @return
     */
    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory)
    {
        StringRedisTemplate template = new StringRedisTemplate(factory);
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}
application.properties
# REDIS (RedisProperties)--------------------------------------------------------------------------
# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器连接端口
spring.redis.port=6379
## 单个redis服务配置
spring.redis.host=47.104.22.231
#spring.redis.cluster.nodes=47.104.22.231:6379,47.104.22.231:6380,47.104.22.231:6381,47.104.22.231:6382,47.104.22.231:6383,47.104.22.231:6384
# Redis服务器连接密码(默认为空)
spring.redis.password=mlgd
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=6000
# REDIS (RedisProperties)----------------------------------------------------










