lute
lute

Reputation: 392

Combine Netty and Spring MVC

How can I configure Netty in Spring MVC. When and where should I start the Netty tcp server? Should I init netty once the Spring starts? Could someone show me an example such as the Spring configuration xml file or something eles? Thanks!

Upvotes: 8

Views: 19781

Answers (4)

Boris Treukhov
Boris Treukhov

Reputation: 17774

Actually with Spring 5 you can configure a Spring 5 Webflux application instead, it looks like a robust reactive alternative. The following lines (Config.start()) run a small HTTP server in parallel with the main execution with a Spring context.

@Configuration
public class Config extends DelegatingWebFluxConfiguration{
    @Bean
    String test(){
        return "Hello WOrLd";
    }

    @Bean
    AdminController controller(){
        return new AdminController();
    }

    public static void start() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class);
        HttpHandler handler = WebHttpHandlerBuilder.applicationContext(applicationContext).build();
        ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(handler);
        HttpServer.create("0.0.0.0", 8082).newHandler(adapter).subscribe();
    }
}

controller code:

@RestController
public class AdminController {
    @Autowired
    String text;

    @GetMapping(path = "/commands")
    Mono<String> commands(){
        return Mono.just(text);
    }
}

build.gradle

 compile 'org.springframework:spring-context:5.0.2.RELEASE'
 compile 'org.springframework:spring-web:5.0.2.RELEASE'
 compile 'org.springframework:spring-webflux:5.0.2.RELEASE'
 compile 'io.projectreactor.ipc:reactor-netty:0.7.2.RELEASE'

P.S. this example only uses Spring without Spring Boot which as good as a side embedded web server, but you should consider using Spring Boot for a full-fledged microservice development.

Upvotes: 0

Anton Shchastnyi
Anton Shchastnyi

Reputation: 3870

Option 1 (Just the code):
Here's a really good example showing how to bootstrap Netty with a handler supporting Servlets (which in turn will delegate the job to Spring MVC) https://github.com/rstoyanchev/netty-spring-mvc

There you define ServletNettyHandler plus Java-based Spring MVC configurer (DispatcherServletChannelInitializer), and the TestController uses @Controller & @RequestMapping annotations as it always does in these cases.

Notes: Consider updating Netty & Spring version of the example to get it work.

Option 2 (Just the blog post):
I've found a blog post describing the process. http://www.hypersocket.com/content/?p=12

Upvotes: 1

Jonathan
Jonathan

Reputation: 20375

Just create a bean with start and stop methods that are responsible for starting up and shutting down the Netty server and then register the bean in the context with appropriate init and destroy hooks, e.g.:

<bean id="myNettyServer" class="x.y.z.MyNettyServer" init-method="start" destroy-method="shutdown"/>

Or alternatively use @PostConstruct and @PreDestroy annotations if you don't want to use XML configuration.

Upvotes: 1

seanhodges
seanhodges

Reputation: 17524

It really depends what you are using Netty for. Assuming you are using it as an embedded HTTP server running on a separate port, you could simply initialise it within a Spring bean. I've achieved this in the past using a useful Netty/Atmosphere wrapper called Nettosphere:

@Service
public class NettyServer implements ServletContextAware {

    private ServletContext servletContext;

    private Nettosphere server;

    @Autowired
    private MyStatusHandler statusHandler;

    @PostConstruct
    public void initialiseNettyServer() {
            String rootPath = servletContext.getContextPath() + "/api";

            server = new Nettosphere.Builder().config(
                    new Config.Builder()
                            .host(SERVER_HOST)
                            .port(SERVER_PORT)
                            .resource(rootPath + "/status", statusHandler)
                            .build())
                     .build();
            server.start();
    }

    @PreDestroy
    public void shutdownNettyServer() {
            server.stop();
    }

}

This assumes the annotation-based configuration in Spring, you can easily achieve the same result using XML as explained in Jonathan's answer.

Of course, you may prefer to use Netty directly, in which case the same principle applies, but you will need to dig into the Netty user guide a bit to bootstrap the server correctly.

Upvotes: 4

Related Questions