使用Spring+Maven配置Netty4

4 篇文章 0 订阅
3 篇文章 0 订阅

使用Spring+Maven配置Netty4

原文:http://nerdronix.blogspot.com/2013/06/netty-4-configuration-using-spring-maven.html (需要翻墙)

本文介绍如何使用Spring3.2和Maven配置Netty 4. 源码在github. Spring的配置使用的是纯Java配置没有涉及xml文件. 在本文的最后, 也会有相应的xml文件的配置.

Netty

为了创建一个netty服务端, 通常我们需要以下几个步骤:

  • 创建ServerBootstrap对象
  • 设置参数像bossGroup, workerGroup, childHandler以及设置ChannelOption就像keep_alive针对bootstrap.
  • 使用bootstrap创建channel.
  • 确保可以退出程序, 你调用shutDownGracefully方法或者相似的方法.

现在假设你已经在Spring中创建了bootstrap, 下面这几行代码足够启动服务端以及关闭.

1 @PostConstruct
2 public void start() throws Exception {
3     serverChannel = b.bind(tcpPort).sync().channel().closeFuture().sync().channel()
4 }
5  
6 @PreDestroy
7 public void stop() {
8     serverChannel.close();
9 }

其中的"b"就是bootstrap通过Spring注入得到. 你可以查看完整代码TCPServer.

Spring

涉及到一点针对Netty的Spring配置.  必须配置ServerBootstrap, ChannelInitializer和ChannelOption以及一些解码器和编码器, 这个例子更加的深入. 这几行代码是Spring配置的说明. 完整代码在SpringConfig

注解


1 @Configuration
2 @ComponentScan("org.nerdronix")
3 @PropertySource("classpath:netty-server.properties")
4 public class SpringConfig { ...

 


@Configuration注解确保java文件可以像近似于Spring的application-context.xml文件一样的方式处理. 组件扫描特性被用来设置通过Spring将被扫描到的一个或多个包自动装配. 注意任何需要被Spring管理的POJO都应该带上@Component注意或者子注解. 稍后会有更多关于@PropertySource注解.
现在我们往下到第2步, 即真实的bean发生在SpringConfig中的初始化过程.

Bean的创建

下面的代码展示如何创建一个bean.


1 @Bean(name = "bossGroup", destroyMethod = "shutdownGracefully")
2 public NioEventLoopGroup bossGroup() {
3     return new NioEventLoopGroup(bossCount);
4 }

@Bean注解被用来表示这个方法将会返回一个bean, 注解的destroyMethod参数意味着Spring退出时将被调用. 这是个可选参数, 连"name"都是可选的. 因此bossCount来自哪里? 我们到第3步, 去解释下.


PropertySource的配置.

Spring3.1引入了一种方法, 即使用下面这两个注解, @PropertySource和@Value, 可以用很简单的方式注意一个bean的属性. 

1 @PropertySource("classpath:netty-server.properties")
2 ...
3 ...
4 @Value("${boss.thread.count}")
5 private int bossCount;

另外对于纯java的配置方案, 你还需要在SpringConfig类中设置接下来的bean, 否则这些不会被@Value注解正确的评估.  

1 /**
2 * Necessary to make the @Value annotations work.
3 *
4 */
5 @Bean
6 public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
7     return new PropertySourcesPlaceholderConfigurer();
8 }

在netty-server.properties文件中相应的条目是boss.thread.count=2. 注意Spring将自动转换由string到integer, 这种做法针对所有常见数据类型, 所以你不需要调用Integer.valueOf(string).


设置Netty Bootstrap

下面的代码片断展示netty bootstrap如何设置.

01 @Bean(name = "serverBootstrap")
02 public ServerBootstrap bootstrap() {
03     ServerBootstrap b = new ServerBootstrap();
04     b.group(bossGroup(), workerGroup())
05         .channel(NioServerSocketChannel.class)
06         .childHandler(protocolInitalizer);
07     Map, Object> tcpChannelOptions = tcpChannelOptions();
08     Set> keySet = tcpChannelOptions.keySet();
09     for (@SuppressWarnings("rawtypes")
10         ChannelOption option : keySet) {
11             b.option(option, tcpChannelOptions.get(option));
12     }
13     return b;
14 }

protocolInitalizer你可以找到真实的POJO,位于另一个包的 这里. 那么我们如何在SpringConfig类中得到这个bean? 答案是SpringConfig的@Configuration注解也继承了@Component注解意味着SpringConfig也是一个 Spring类, 而且我们可以自动装配其他bean到这个bean, 就像任何其他的普通Spring bean. 
下面几行SpringConfig文件中的代码可以做好这件事 

1 @Autowired
2 @Qualifier("springProtocolInitializer")
3 private StringProtocolInitalizer protocolInitalizer;

控制反转的好处是所有的bean被默认是单例你不需要花费任何精力, spring的组件扫描功能会负责自动写程序并且使用@PropertySource和@Value注解属性被轻松的注入. 依照接口编程的示例你可以让你的代码成为真正的模块. 

Maven 


pom相当的清晰; 你需要添加针对Spring, netty和logging的依赖库让他工作. 主要的依赖库会在下面提供, 父级的pom包括所有的版本和常用依赖库. 

01 <dependency>
02     <groupId>io.netty</groupId>
03     <artifactId>netty-all</artifactId>
04     <version>${netty.version}</version>
05 </dependency>
06  
07 <dependency>
08     <groupId>org.springframework</groupId>
09     <artifactId>spring-context</artifactId>
10     <version>${org.springframework.version}</version>
11 </dependency>

最后, 运行!

找到Main类执行他, Netty服务端应该启动并监听在netty-server.properties文件中设置的端口, 即localhost:8090.

我想要XML!

好吧, 你还是在2009年噢! 实际上, 我仍然热爱针对bean的关系图的XML文件并且使用工具构建, 虽然纯Java的选项肯定赢我. 不管怎么样, 在这: 虽然不是完整的例子但是他展示的是最有意义的bean.

01 <dependency>
02     <groupId>io.netty</groupId>
03     <artifactId>netty-all</artifactId>
04     <vers<bean id="bossGroup" class="io.netty.channel.nio.NioEventLoopGroup">
05         <constructor-arg type="int" index="0" value="${boss.thread.count}" />
06         <constructor-arg index="1" ref="bossThreadFactory" />
07         </bean>
08  
09         <bean id="workerGroup" class="io.netty.channel.nio.NioEventLoopGroup">
10             <constructor-arg type="int" index="0" value="${worker.thread.count}" />
11             <constructor-arg index="1" ref="workerThreadFactory" />
12         </bean>
13  
14         <bean id="bossThreadFactory" class="org.nerdronix.NamedThreadFactory">
15             <constructor-arg type="String" value="Server-Boss" />
16         </bean>
17  
18         <bean id="workerThreadFactory" class="org.nerdronix.NamedThreadFactory">
19             <constructor-arg type="String" index="0" value="Server-Worker" />
20         </bean>
21  
22            
23             <!-- Netty options for server bootstrap -->
24         <util:map id="tcpChannelOptions" map-class="java.util.HashMap">
25             <entry>
26                 <key><util:constant static-field="io.netty.channel.ChannelOption.SO_KEEPALIVE"/></key>
27                 <value type="java.lang.Boolean">${so.keepalive}</value>
28             </entry>
29             <entry>
30                 <key><util:constant static-field="io.netty.channel.ChannelOption.SO_BACKLOG"/></key>
31                 <value type="java.lang.Integer">${so.backlog}</value>
32             </entry>
33         </util:map>
34 </dependency>

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
       在Java界,Netty无疑是开发网络应用的拿手菜。你不需要太多关注复杂的NIO模型和底层网络的细节,使用其丰富的接口,可以很容易的实现复杂的通讯功能。 本课程准备的十二个实例,按照由简单到复杂的学习路线,让你能够快速学习如何利用Netty来开发网络通信应用。                每个实例简洁、清爽、实用,重点在“用”上,即培训大家如何熟练的使用Netty解决实际问题,抛弃以往边讲应用边分析源码的培训模式所带来的“高不成低不就”情况,在已经能够熟练使用、并且清楚开发流程的基础上再去分析源码就会思路清晰、事半功倍。        本套课程的十二个实例,各自独立,同时又层层递进,每个实例都是针对典型的实际应用场景,学了马上就能应用到实际项目中去。 学习好Netty 总有一个理由给你惊喜!! 一、应用场景        Netty已经众多领域得到大规模应用,这些领域包括:物联网领域、互联网领域、电信领域、大数据领域、游戏行业、企业应用、银行证券金融领域、。。。  二、技术深度        多款开源框架中应用了Netty,如阿里分布式服务框架 Dubbo 的 RPC 框架、淘宝的消息中间件 R0cketMQ、Hadoop 的高性能通信和序列化组件 Avro 的 RPC 框架、开源集群运算框架 Spark、分布式计算框架 Storm、并发应用和分布式应用 Akka、。。。  三、就业前景         很多大厂在招聘高级/资深Java工程师时要求熟练学习、或熟悉Netty,下面只是简要列出,这个名单可以很长。。。
下面是一个简单的 Spring Boot 应用程序中使用 Netty 的 ServerBootstrap 和 Bootstrap 来创建服务器和客户端的示例: 1. 首先,需要在 Maven 中添加以下依赖项: ```xml <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.65.Final</version> </dependency> ``` 2. 创建 Netty 服务器的代码: ```java @Component public class NettyServer { private final EventLoopGroup bossGroup = new NioEventLoopGroup(); private final EventLoopGroup workerGroup = new NioEventLoopGroup(); @Autowired private NettyServerInitializer nettyServerInitializer; public void start() throws InterruptedException { ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(nettyServerInitializer); ChannelFuture future = bootstrap.bind(8080).sync(); future.channel().closeFuture().sync(); } @PreDestroy public void stop() { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } ``` 3. 创建 Netty 服务器的初始化器: ```java @Component public class NettyServerInitializer extends ChannelInitializer<SocketChannel> { @Autowired private NettyServerHandler nettyServerHandler; @Override protected void initChannel(SocketChannel ch) { ch.pipeline().addLast(nettyServerHandler); } } ``` 4. 创建 Netty 服务器的处理器: ```java @Component public class NettyServerHandler extends SimpleChannelInboundHandler<String> { @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) { // 处理接收到的数据 System.out.println("Received message: " + msg); ctx.writeAndFlush("Server response: " + msg); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // 处理异常 cause.printStackTrace(); ctx.close(); } } ``` 5. 创建 Netty 客户端的代码: ```java @Component public class NettyClient { private final EventLoopGroup group = new NioEventLoopGroup(); @Autowired private NettyClientInitializer nettyClientInitializer; public String sendMessage(String host, int port, String message) throws InterruptedException, ExecutionException { Bootstrap bootstrap = new Bootstrap(); bootstrap.group(group) .channel(NioSocketChannel.class) .handler(nettyClientInitializer); ChannelFuture future = bootstrap.connect(host, port).sync(); future.channel().writeAndFlush(message).sync(); future.channel().closeFuture().sync(); return nettyClientInitializer.getResponse(); } @PreDestroy public void stop() { group.shutdownGracefully(); } } ``` 6. 创建 Netty 客户端的初始化器: ```java @Component public class NettyClientInitializer extends ChannelInitializer<SocketChannel> { private String response; @Override protected void initChannel(SocketChannel ch) { ch.pipeline().addLast(new StringEncoder(), new StringDecoder(), new NettyClientHandler(this)); } public String getResponse() { return response; } public void setResponse(String response) { this.response = response; } } ``` 7. 创建 Netty 客户端的处理器: ```java public class NettyClientHandler extends SimpleChannelInboundHandler<String> { private final NettyClientInitializer nettyClientInitializer; public NettyClientHandler(NettyClientInitializer nettyClientInitializer) { this.nettyClientInitializer = nettyClientInitializer; } @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) { // 处理接收到的数据 nettyClientInitializer.setResponse(msg); ctx.close(); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // 处理异常 cause.printStackTrace(); ctx.close(); } } ``` 在 Spring Boot 应用程序中使用 Netty 的 ServerBootstrap 和 Bootstrap 来创建服务器和客户端,需要将 Netty 服务器和客户端的 Bean 注入到 Spring 容器中,并在需要使用使用它们。例如,在控制器中使用 Netty 客户端: ```java @RestController @RequestMapping("/netty") public class NettyController { @Autowired private NettyClient nettyClient; @GetMapping("/send") public String sendMessage() throws InterruptedException, ExecutionException { return nettyClient.sendMessage("localhost", 8080, "Hello from client"); } } ``` 这样,当访问 /netty/send 路径时,将会向 Netty 服务器发送消息并接收响应。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值