{"id":15001755,"url":"https://github.com/xxlabaza/netty-spring-boot-starter","last_synced_at":"2025-07-25T05:06:23.527Z","repository":{"id":57729838,"uuid":"245236169","full_name":"xxlabaza/netty-spring-boot-starter","owner":"xxlabaza","description":"A Spring Boot starter for Netty clients and servers","archived":false,"fork":false,"pushed_at":"2020-03-06T06:40:38.000Z","size":75,"stargazers_count":9,"open_issues_count":1,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-08T15:07:07.223Z","etag":null,"topics":["netty","netty-client","netty-server","spring","spring-boot"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xxlabaza.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-03-05T18:15:33.000Z","updated_at":"2024-08-11T22:27:20.000Z","dependencies_parsed_at":"2022-09-10T21:51:28.919Z","dependency_job_id":null,"html_url":"https://github.com/xxlabaza/netty-spring-boot-starter","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/xxlabaza/netty-spring-boot-starter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xxlabaza%2Fnetty-spring-boot-starter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xxlabaza%2Fnetty-spring-boot-starter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xxlabaza%2Fnetty-spring-boot-starter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xxlabaza%2Fnetty-spring-boot-starter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xxlabaza","download_url":"https://codeload.github.com/xxlabaza/netty-spring-boot-starter/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xxlabaza%2Fnetty-spring-boot-starter/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266959623,"owners_count":24012531,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-25T02:00:09.625Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["netty","netty-client","netty-server","spring","spring-boot"],"created_at":"2024-09-24T18:05:33.997Z","updated_at":"2025-07-25T05:06:23.489Z","avatar_url":"https://github.com/xxlabaza.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Overview\n\n[![build_status](https://travis-ci.org/xxlabaza/netty-spring-boot-starter.svg?branch=master)](https://travis-ci.org/xxlabaza/netty-spring-boot-starter)\n[![maven_central](https://maven-badges.herokuapp.com/maven-central/com.xxlabaza.utils/netty-spring-boot-starter/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.xxlabaza.utils/netty-spring-boot-starter)\n[![License](http://img.shields.io/:license-apache-brightgreen.svg)](http://www.apache.org/licenses/LICENSE-2.0.html)\n\nSpring boot starter that provides auto-configuration for [Netty](https://netty.io) clients and servers.\n\n## Usage\n\nThe minimal project could look like this:\n\nMaven's **pom.xml**:\n\n```xml\n  \u003cdependencies\u003e\n    ...\n    \u003cdependency\u003e\n      \u003cgroupId\u003ecom.xxlabaza.utils\u003c/groupId\u003e\n      \u003cartifactId\u003enetty-spring-boot-starter\u003c/artifactId\u003e\n      \u003cversion\u003e1.0.0\u003c/version\u003e\n    \u003c/dependency\u003e\n    ...\n  \u003c/dependencies\u003e\n```\n\nYour single **Main.java** with an echo server handler:\n\n```java\nimport io.netty.channel.ChannelHandler;\nimport io.netty.channel.ChannelHandler.Sharable;\nimport io.netty.channel.ChannelHandlerContext;\nimport io.netty.channel.ChannelInboundHandlerAdapter;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.context.annotation.Bean;\n\n@SpringBootApplication\npublic class Main {\n\n  public static void main (String[] args) {\n    SpringApplication.run(Main.class, args);\n  }\n\n  @Bean\n  ChannelHandler echoChannelHandler () {\n    return new EchoChannelHandler();\n  }\n\n  @Sharable\n  class EchoChannelHandler extends ChannelInboundHandlerAdapter {\n\n    @Override\n    public void channelRead (ChannelHandlerContext context, Object object) throws Exception {\n      context.writeAndFlush(object);\n    }\n  }\n}\n```\n\nAnd **application.yml** (see [NettyClientProperties](src/main/java/com/xxlabaza/utils/netty/config/client/NettyClientProperties.java) and [NettyServerProperties](src/main/java/com/xxlabaza/utils/netty/config/server/NettyServerProperties.java) for the full properties lists):\n\n```yml\nspring:\n  application.name: echo-server\n\nxxlabaza.netty.server:\n  # the value could be just port, like here,\n  # or a complete string like localhost:9090\n  bind: 9090\n```\n\nSo, the code above creates and runs the Echo server on port **9090**. We can see it during the start process (pay attention on **NettyServersApplicationListener** and **NettyServer** log records):\n\n```bash\n\u003e mvn package; java -jar target/my-netty-server-1.0.0.jar\n\n  .   ____          _            __ _ _\n /\\\\ / ___'_ __ _ _(_)_ __  __ _ \\ \\ \\ \\\n( ( )\\___ | '_ | '_| | '_ \\/ _` | \\ \\ \\ \\\n \\\\/  ___)| |_)| | | | | || (_| |  ) ) ) )\n  '  |____| .__|_| |_|_| |_\\__, | / / / /\n =========|_|==============|___/=/_/_/_/\n :: Spring Boot ::        (v2.2.5.RELEASE)\n\n2020-03-05 21:38:09.776  INFO 19438 --- [           main] com.xxlabaza.test.my.netty.server.Main   : Starting Main on IB-ALABAZIN-M with PID 19438 (/Users/alabazin/jp/my-netty-server/target/my-netty-server-1.0.0.jar started by alabazin in /Users/alabazin/jp/my-netty-server)\n2020-03-05 21:38:09.783  INFO 19438 --- [           main] com.xxlabaza.test.my.netty.server.Main   : No active profile set, falling back to default profiles: default\n2020-03-05 21:38:10.466  INFO 19438 --- [           main] .n.c.s.l.NettyServersApplicationListener : starting NettyServer(bind=0.0.0.0/0.0.0.0:9090)\n2020-03-05 21:38:10.519  INFO 19438 --- [           main] com.xxlabaza.utils.netty.NettyServer     : started NettyServer(bind=0.0.0.0/0.0.0.0:9090)\n2020-03-05 21:38:10.527  INFO 19438 --- [           main] com.xxlabaza.test.my.netty.server.Main   : Started Main in 2.336 seconds (JVM running for 3.144)\n```\n\nYep, that was easy, but let's imagine that we need a second `ChannelHandler` for, let's say, logging. The following code illustrates that situation:\n\n**Main.java**:\n\n```java\nimport static io.netty.handler.logging.LogLevel.INFO;\n\nimport io.netty.channel.ChannelHandler;\nimport io.netty.channel.ChannelHandler.Sharable;\nimport io.netty.handler.logging.LoggingHandler;\nimport io.netty.channel.ChannelHandlerContext;\nimport io.netty.channel.ChannelInboundHandlerAdapter;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.core.annotation.Order;\n\n@SpringBootApplication\npublic class Main {\n\n  public static void main (String[] args) {\n    SpringApplication.run(Main.class, args);\n  }\n\n  @Bean\n  @Order(0)\n  ChannelHandler loggingChannelHandler () {\n    return new LoggingHandler(INFO);\n  }\n\n  @Bean\n  @Order(1)\n  ChannelHandler echoChannelHandler () {\n    return new EchoChannelHandler();\n  }\n\n  @Sharable\n  class EchoChannelHandler extends ChannelInboundHandlerAdapter {\n\n    @Override\n    public void channelRead (ChannelHandlerContext context, Object object) throws Exception {\n      context.writeAndFlush(object);\n    }\n  }\n}\n```\n\nNote, I used the **@Order** annotation on top of the beans, because I wanted to specify their order in a channel initializer *pipeline*.\n\nAfter the starting and receiving a message we can see the following picture:\n\n```bash\n\u003e mvn package; java -jar target/my-netty-server-1.0.0.jar\n\n  .   ____          _            __ _ _\n /\\\\ / ___'_ __ _ _(_)_ __  __ _ \\ \\ \\ \\\n( ( )\\___ | '_ | '_| | '_ \\/ _` | \\ \\ \\ \\\n \\\\/  ___)| |_)| | | | | || (_| |  ) ) ) )\n  '  |____| .__|_| |_|_| |_\\__, | / / / /\n =========|_|==============|___/=/_/_/_/\n :: Spring Boot ::        (v2.2.5.RELEASE)\n\n2020-03-05 21:44:48.600  INFO 19874 --- [           main] com.xxlabaza.test.my.netty.server.Main   : Starting Main on IB-ALABAZIN-M with PID 19874 (/Users/alabazin/jp/my-netty-server/target/my-netty-server-1.0.0.jar started by alabazin in /Users/alabazin/jp/my-netty-server)\n2020-03-05 21:44:48.604  INFO 19874 --- [           main] com.xxlabaza.test.my.netty.server.Main   : No active profile set, falling back to default profiles: default\n2020-03-05 21:44:49.314  INFO 19874 --- [           main] .n.c.s.l.NettyServersApplicationListener : starting NettyServer(bind=0.0.0.0/0.0.0.0:9090)\n2020-03-05 21:44:49.388  INFO 19874 --- [           main] com.xxlabaza.utils.netty.NettyServer     : started NettyServer(bind=0.0.0.0/0.0.0.0:9090)\n2020-03-05 21:44:49.400  INFO 19874 --- [           main] com.xxlabaza.test.my.netty.server.Main   : Started Main in 1.37 seconds (JVM running for 2.277)\n2020-03-05 21:46:42.707  INFO 19874 --- [orkers-pool-3-2] io.netty.handler.logging.LoggingHandler  : [id: 0x1fa457ae, L:/127.0.0.1:9090 - R:/127.0.0.1:65422] REGISTERED\n2020-03-05 21:46:42.708  INFO 19874 --- [orkers-pool-3-2] io.netty.handler.logging.LoggingHandler  : [id: 0x1fa457ae, L:/127.0.0.1:9090 - R:/127.0.0.1:65422] ACTIVE\n2020-03-05 21:46:44.280  INFO 19874 --- [orkers-pool-3-2] io.netty.handler.logging.LoggingHandler  : [id: 0x1fa457ae, L:/127.0.0.1:9090 - R:/127.0.0.1:65422] READ: 6B\n         +-------------------------------------------------+\n         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |\n+--------+-------------------------------------------------+----------------+\n|00000000| 70 6f 70 61 0d 0a                               |popa..          |\n+--------+-------------------------------------------------+----------------+\n2020-03-05 21:46:44.281  INFO 19874 --- [orkers-pool-3-2] io.netty.handler.logging.LoggingHandler  : [id: 0x1fa457ae, L:/127.0.0.1:9090 - R:/127.0.0.1:65422] WRITE: 6B\n         +-------------------------------------------------+\n         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |\n+--------+-------------------------------------------------+----------------+\n|00000000| 70 6f 70 61 0d 0a                               |popa..          |\n+--------+-------------------------------------------------+----------------+\n2020-03-05 21:46:44.281  INFO 19874 --- [orkers-pool-3-2] io.netty.handler.logging.LoggingHandler  : [id: 0x1fa457ae, L:/127.0.0.1:9090 - R:/127.0.0.1:65422] FLUSH\n2020-03-05 21:46:44.283  INFO 19874 --- [orkers-pool-3-2] io.netty.handler.logging.LoggingHandler  : [id: 0x1fa457ae, L:/127.0.0.1:9090 - R:/127.0.0.1:65422] READ COMPLETE\n```\n\nNow you can see the logs of the inbound and outbound messages in the console.\n\nUnfortunately, not all `ChannelHandler`s are stateless and can have a **@Share** annotation on top of the class. Sometimes we need a state inside a `ChannelHandler`, and we would like to have separate instances for each new connection. For that purposes, you can use `ChannelHandlerProvider`, which *supplies* the new instances of a specified `ChannelHandler`, like in this example:\n\n```java\n...\nimport static java.lang.Integer.MAX_VALUE;\n\nimport com.xxlabaza.utils.netty.handler.ChannelHandlerProvider;\nimport io.netty.handler.codec.LengthFieldBasedFrameDecoder;\nimport java.util.function.Supplier;\n...\n  @Bean\n  @Order(2)\n  ChannelHandler lengthFieldBasedFrameDecoder () {\n    Supplier\u003cChannelHandler\u003e supplier = () -\u003e new LengthFieldBasedFrameDecoder(MAX_VALUE, 0, 2);\n    return ChannelHandlerProvider.from(supplier);\n  }\n...\n```\n\nIn the code above, we created a `ChannelHandler` supplier and put it in the `ChannelHandlerProvider` instance, which will provide the new instances for each new connection in our channel initializer.\n\nOk. Looks awesome, but what about a client? Let's add one:\n\nIn **application.yml** I added a section with the client's settings:\n\n```yml\nspring:\n  application.name: echo-server\n\nxxlabaza.netty:\n  server:\n    bind: 9090\n  client:\n     # the value, same as server.bindm could be just port, like here,\n     # or a complete string like localhost:9090\n    connect: 9090\n```\n\n**Main.java** now contains two `ChannelInitializer`s declarations (**NettyClientChannelInitializer** for client and **NettyServerChannelInitializer** for server) to determine which Spring context's beans to use for the client and which for the server:\n\n```java\nimport static io.netty.handler.logging.LogLevel.INFO;\n\nimport com.xxlabaza.utils.netty.config.client.builder.NettyClientChannelInitializer;\nimport com.xxlabaza.utils.netty.config.server.builder.NettyServerChannelInitializer;\nimport com.xxlabaza.utils.netty.handler.ChannelHandlerInitializerPipeline;\n\nimport io.netty.channel.ChannelHandler;\nimport io.netty.channel.ChannelHandler.Sharable;\nimport io.netty.handler.logging.LoggingHandler;\nimport io.netty.channel.ChannelHandlerContext;\nimport io.netty.channel.ChannelInboundHandlerAdapter;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.context.annotation.Bean;\n\n@SpringBootApplication\npublic class Main {\n\n  public static void main (String[] args) {\n    SpringApplication.run(Main.class, args);\n  }\n\n  @Bean\n  NettyClientChannelInitializer clientChannelInitializer () {\n    return ChannelHandlerInitializerPipeline.clientPipeline(\n        emptyChannelHandler()\n    );\n  }\n\n  @Bean\n  NettyServerChannelInitializer serverChannelInitializer () {\n    return ChannelHandlerInitializerPipeline.serverPipeline(\n        loggingChannelHandler(),\n        echoChannelHandler()\n    );\n  }\n\n  @Bean\n  ChannelHandler loggingChannelHandler () {\n    return new LoggingHandler(INFO);\n  }\n\n  @Bean\n  ChannelHandler echoChannelHandler () {\n    return new EchoChannelHandler();\n  }\n\n  @Bean\n  ChannelHandler emptyChannelHandler () {\n    return new EmptyChannelHandler();\n  }\n\n  @Sharable\n  class EchoChannelHandler extends ChannelInboundHandlerAdapter {\n\n    @Override\n    public void channelRead (ChannelHandlerContext context, Object object) throws Exception {\n      context.writeAndFlush(object);\n    }\n  }\n\n  @Sharable\n  class EmptyChannelHandler extends ChannelInboundHandlerAdapter {\n\n  }\n}\n```\n\nThe client has a single `EmptyChannelHandler` (doesn't do anything) and connects to the server automatically (thanks for **xxlabaza.netty.client.auto-connect** property in `true`, by default). We can see that behavior with the help of the `loggingChannelHandler`:\n\n```bash\n\u003e mvn package; java -jar target/my-netty-server-1.0.0.jar\n\n  .   ____          _            __ _ _\n /\\\\ / ___'_ __ _ _(_)_ __  __ _ \\ \\ \\ \\\n( ( )\\___ | '_ | '_| | '_ \\/ _` | \\ \\ \\ \\\n \\\\/  ___)| |_)| | | | | || (_| |  ) ) ) )\n  '  |____| .__|_| |_|_| |_\\__, | / / / /\n =========|_|==============|___/=/_/_/_/\n :: Spring Boot ::        (v2.2.5.RELEASE)\n\n2020-03-05 23:17:03.901  INFO 26205 --- [           main] com.xxlabaza.test.my.netty.server.Main   : Starting Main on IB-ALABAZIN-M with PID 26205 (/Users/alabazin/jp/my-netty-server/target/my-netty-server-1.0.0.jar started by alabazin in /Users/alabazin/jp/my-netty-server)\n2020-03-05 23:17:03.904  INFO 26205 --- [           main] com.xxlabaza.test.my.netty.server.Main   : No active profile set, falling back to default profiles: default\n2020-03-05 23:17:04.677  INFO 26205 --- [           main] .n.c.s.l.NettyServersApplicationListener : starting NettyServer(bind=0.0.0.0/0.0.0.0:9090)\n2020-03-05 23:17:04.751  INFO 26205 --- [           main] com.xxlabaza.utils.netty.NettyServer     : started NettyServer(bind=0.0.0.0/0.0.0.0:9090)\n2020-03-05 23:17:04.758  INFO 26205 --- [           main] u.n.c.c.l.NettyClientApplicationListener : starting NettyClient(remote=0.0.0.0/0.0.0.0:9090)\n2020-03-05 23:17:04.773  INFO 26205 --- [           main] com.xxlabaza.utils.netty.NettyClient     : started NettyClient(remote=0.0.0.0/0.0.0.0:9090)\n2020-03-05 23:17:04.782  INFO 26205 --- [           main] com.xxlabaza.test.my.netty.server.Main   : Started Main in 1.408 seconds (JVM running for 2.606)\n2020-03-05 23:17:04.799  INFO 26205 --- [       pool-1-1] io.netty.handler.logging.LoggingHandler  : [id: 0x2ab2a057, L:/10.116.52.78:9090 - R:/10.116.52.78:50381] REGISTERED\n2020-03-05 23:17:04.800  INFO 26205 --- [       pool-1-1] io.netty.handler.logging.LoggingHandler  : [id: 0x2ab2a057, L:/10.116.52.78:9090 - R:/10.116.52.78:50381] ACTIVE\n```\n\nHey, but what if I want to have several clients or servers in the same Spring application context? Well, there are two special config classes for that: `NettyServerConfig` and `NettyClientConfig`. You can easily use them for creating so many clients and servers as you want:\n\nLet's add one more client and server to the **application.yml**:\n\n```yml\nspring:\n  application.name: echo-server\n\nxxlabaza.netty:\n  server:\n    bind: 9990\n  client:\n    connect: 9990\n\nmy.long.prefix.server:\n  bind: 9901\n\nmy.long.prefix.client:\n  connect: 9901\n  auto-connect: false\n```\n\nThen, we add according configurations to **Main.java**:\n\n```java\nimport static com.xxlabaza.utils.netty.handler.ChannelHandlerInitializerPipeline.clientPipeline;\nimport static com.xxlabaza.utils.netty.handler.ChannelHandlerInitializerPipeline.pipelineOf;\nimport static com.xxlabaza.utils.netty.handler.ChannelHandlerInitializerPipeline.serverPipeline;\nimport static io.netty.handler.logging.LogLevel.INFO;\n\nimport com.xxlabaza.utils.netty.config.client.NettyClientConfig;\nimport com.xxlabaza.utils.netty.config.client.builder.NettyClientChannelInitializer;\nimport com.xxlabaza.utils.netty.config.server.NettyServerConfig;\nimport com.xxlabaza.utils.netty.config.server.builder.NettyServerChannelInitializer;\n\nimport io.netty.channel.ChannelHandler;\nimport io.netty.channel.ChannelHandler.Sharable;\nimport io.netty.handler.logging.LoggingHandler;\nimport io.netty.channel.ChannelHandlerContext;\nimport io.netty.channel.ChannelInboundHandlerAdapter;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.context.annotation.Bean;\n\n@SpringBootApplication\npublic class Main {\n\n  public static void main (String[] args) {\n    SpringApplication.run(Main.class, args);\n  }\n\n  @Bean\n  NettyServerConfig secondServer () {\n    return NettyServerConfig.builder()\n        .propertiesPrefix(\"my.long.prefix.server\")\n        .channelInitializer(pipelineOf(\n            echoChannelHandler()\n        ))\n        .build();\n  }\n\n  @Bean\n  NettyClientConfig secondClient () {\n    return NettyClientConfig.builder()\n        .propertiesPrefix(\"my.long.prefix.client\")\n        .build();\n  }\n\n  @Bean\n  NettyClientChannelInitializer clientChannelInitializer () {\n    return clientPipeline(\n        emptyChannelHandler()\n    );\n  }\n\n  @Bean\n  NettyServerChannelInitializer serverChannelInitializer () {\n    return serverPipeline(\n        loggingChannelHandler(),\n        echoChannelHandler()\n    );\n  }\n\n  @Bean\n  ChannelHandler loggingChannelHandler () {\n    return new LoggingHandler(INFO);\n  }\n\n  @Bean\n  ChannelHandler echoChannelHandler () {\n    return new EchoChannelHandler();\n  }\n\n  @Bean\n  ChannelHandler emptyChannelHandler () {\n    return new EmptyChannelHandler();\n  }\n\n  @Sharable\n  class EchoChannelHandler extends ChannelInboundHandlerAdapter {\n\n    @Override\n    public void channelRead (ChannelHandlerContext context, Object object) throws Exception {\n      context.writeAndFlush(object);\n    }\n  }\n\n  @Sharable\n  class EmptyChannelHandler extends ChannelInboundHandlerAdapter {\n\n  }\n}\n```\n\nWhat do we have here?\n1. The default client and server, because we specified the **xxlabaza.netty.** prefix in the **application.yml**;\n2. a **secondServer** instance, which takes its configuration from properties with the prefix **my.long.prefix.server** and has a manually instantiated channel initializer (if you would like, you can customize the other parts of the `NettyServerConfig`);\n3. a **secondClient** bean. It builds from the properties with **my.long.prefix.client** prefix.\n\nSo, the two servers will automatically start with the application context, the default client too (see [NettyClientProperties](src/main/java/com/xxlabaza/utils/netty/config/client/NettyClientProperties.java) and [NettyServerProperties](src/main/java/com/xxlabaza/utils/netty/config/server/NettyServerProperties.java) default values accordingly), but the second client needs to be connected manually (`NettyClient.connect` or `NettyClient.send`):\n\n```bash\n\u003e mvn package; java -jar target/my-netty-server-1.0.0.jar\n\n  .   ____          _            __ _ _\n /\\\\ / ___'_ __ _ _(_)_ __  __ _ \\ \\ \\ \\\n( ( )\\___ | '_ | '_| | '_ \\/ _` | \\ \\ \\ \\\n \\\\/  ___)| |_)| | | | | || (_| |  ) ) ) )\n  '  |____| .__|_| |_|_| |_\\__, | / / / /\n =========|_|==============|___/=/_/_/_/\n :: Spring Boot ::        (v2.2.5.RELEASE)\n\n2020-03-06 02:23:36.263  INFO 30531 --- [           main] com.xxlabaza.test.my.netty.server.Main   : Starting Main on IB-ALABAZIN-M with PID 30531 (/Users/alabazin/jp/my-netty-server/target/my-netty-server-1.0.0.jar started by alabazin in /Users/alabazin/jp/my-netty-server)\n2020-03-06 02:23:36.266  INFO 30531 --- [           main] com.xxlabaza.test.my.netty.server.Main   : No active profile set, falling back to default profiles: default\n2020-03-06 02:23:37.052  INFO 30531 --- [           main] .n.c.s.l.NettyServersApplicationListener : starting NettyServer(bind=0.0.0.0/0.0.0.0:9990)\n2020-03-06 02:23:37.103  INFO 30531 --- [           main] com.xxlabaza.utils.netty.NettyServer     : started NettyServer(bind=0.0.0.0/0.0.0.0:9990)\n2020-03-06 02:23:37.103  INFO 30531 --- [           main] .n.c.s.l.NettyServersApplicationListener : starting NettyServer(bind=0.0.0.0/0.0.0.0:9901)\n2020-03-06 02:23:37.104  INFO 30531 --- [           main] com.xxlabaza.utils.netty.NettyServer     : started NettyServer(bind=0.0.0.0/0.0.0.0:9901)\n2020-03-06 02:23:37.107  INFO 30531 --- [           main] u.n.c.c.l.NettyClientApplicationListener : starting NettyClient(remote=0.0.0.0/0.0.0.0:9990)\n2020-03-06 02:23:37.128  INFO 30531 --- [           main] com.xxlabaza.utils.netty.NettyClient     : started NettyClient(remote=0.0.0.0/0.0.0.0:9990)\n2020-03-06 02:23:37.133  INFO 30531 --- [           main] com.xxlabaza.test.my.netty.server.Main   : Started Main in 1.263 seconds (JVM running for 2.339)\n2020-03-06 02:23:37.143  INFO 30531 --- [orkers-pool-7-2] io.netty.handler.logging.LoggingHandler  : [id: 0x1442fa3d, L:/192.168.236.7:9990 - R:/192.168.236.7:51918] REGISTERED\n2020-03-06 02:23:37.144  INFO 30531 --- [orkers-pool-7-2] io.netty.handler.logging.LoggingHandler  : [id: 0x1442fa3d, L:/192.168.236.7:9990 - R:/192.168.236.7:51918] ACTIVE\n```\n\nAlso, you may want to just configure a `Bootstrap` or a `ServerBootstrap` instance (add additional options or, for example, use a shared `ByteBufAllocator`) before using them, so for that, you can use [NettyClientBootstrapConfigurer](src/main/java/com/xxlabaza/utils/netty/config/client/builder/NettyClientBootstrapConfigurer.java) or [NettyServerBootstrapConfigurer](src/main/java/com/xxlabaza/utils/netty/config/server/builder/NettyServerBootstrapConfigurer.java) interfaces like this:\n\n```java\nimport com.xxlabaza.utils.netty.config.server.builder.NettyServerBootstrapConfigurer;\nimport io.netty.bootstrap.ServerBootstrap;\nimport org.springframework.stereotype.Component;\n\n@Component\nclass MyCustomServerBootstrapConfigurer implements NettyServerBootstrapConfigurer {\n\n  @Override\n  public void configure (ServerBootstrap serverBootstrap) {\n    // do your awesome configuration here\n  }\n}\n```\n\n## Development\n\nThese instructions will get you a copy of the project up and running on your local machine for development and testing purposes.\n\n### Prerequisites\n\nFor building the project you need only a [Java compiler](http://www.oracle.com/technetwork/java/javase/downloads/index.html).\n\n\u003e **IMPORTANT:** the project requires Java version starting from **8**\n\nAnd, of course, you need to clone the project from GitHub:\n\n```bash\n$\u003e git clone https://github.com/xxlabaza/netty-spring-boot-starter\n$\u003e cd netty-spring-boot-starter\n```\n\n### Building\n\nFor building routine automation, I am using [maven](https://maven.apache.org).\n\nTo build the project, do the following:\n\n```bash\n$\u003e ./mvnw compile\n...\n[INFO] ------------------------------------------------------------------------\n[INFO] BUILD SUCCESS\n[INFO] ------------------------------------------------------------------------\n[INFO] Total time:  8.970 s\n[INFO] Finished at: 2020-03-05T21:23:42+03:00\n[INFO] ------------------------------------------------------------------------\n```\n\n### Running the tests\n\nTo run the project's test, do the following:\n\n```bash\n$\u003e ./mvnw test\n...\n[INFO]\n[INFO] Results:\n[INFO]\n[INFO] Tests run: 25, Failures: 0, Errors: 0, Skipped: 0\n[INFO]\n[INFO] ------------------------------------------------------------------------\n[INFO] BUILD SUCCESS\n[INFO] ------------------------------------------------------------------------\n[INFO] Total time:  19.383 s\n[INFO] Finished at: 2020-03-05T21:24:42+03:00\n[INFO] ------------------------------------------------------------------------\n```\n\nAlso, if you do `package` or `install` goals, the tests launch automatically.\n\n## Deploy\n\nTo deploy the project in Maven Central, use the following command:\n\n```bash\n$\u003e ./mvnw \\\n    -DskipAllTests=true \\\n    -Dspotbugs.skip=true \\\n    -Dpmd.skip=true \\\n    -Dcheckstyle.skip \\\n    -Dmaven.javadoc.skip=false \\\n    --settings .settings.xml \\\n    deploy -B\n```\n\nIt maybe usefull to import `gpg`'s secret keys and ownertrust from somewhere:\n\n```bash\n$\u003e echo \"${GPG_SECRET_KEYS}\" | base64 --decode | \"${GPG_EXECUTABLE}\" --batch --passphrase \"${GPG_PASSPHRASE}\" --import\n...\n$\u003e echo \"${GPG_OWNERTRUST}\" | base64 --decode | \"${GPG_EXECUTABLE}\" --batch --passphrase \"${GPG_PASSPHRASE}\" --import-ownertrust\n...\n```\n\n## Built With\n\n* [Java](http://www.oracle.com/technetwork/java/javase) - is a systems and applications programming language\n\n* [Lombok](https://projectlombok.org) - is a java library that spicing up your java\n\n* [Junit](http://junit.org/junit4/) - is a simple framework to write repeatable tests\n\n* [AssertJ](http://joel-costigliola.github.io/assertj/) - AssertJ provides a rich set of assertions, truly helpful error messages, improves test code readability\n\n* [Maven](https://maven.apache.org) - is a software project management and comprehension tool\n\n## Changelog\n\nTo see what has changed in recent versions of the project, see the [changelog](./CHANGELOG.md) file.\n\n## Contributing\n\nPlease read [contributing](./CONTRIBUTING.md) file for details on my code of conduct, and the process for submitting pull requests to me.\n\n## Versioning\n\nWe use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/appulse-projects/utils-java/tags).\n\n## Authors\n\n* **[Artem Labazin](https://github.com/xxlabaza)** - creator and the main developer\n\n## License\n\nThis project is licensed under the Apache License 2.0 License - see the [license](./LICENSE) file for details\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxxlabaza%2Fnetty-spring-boot-starter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxxlabaza%2Fnetty-spring-boot-starter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxxlabaza%2Fnetty-spring-boot-starter/lists"}