Newbie: Netty & Spring

Simon James sjames at btisystems.com
Thu Aug 20 02:49:16 EDT 2009


Thank you for the full and prompt response.
That's very helpful.


Nicholas Hagen wrote:
> 
> As promised, here are some of my latest examples of how I have been  
> using Spring using autowiring and annotations within Spring (version  
> 2.5.6).
> 
> Step 1:
> 
> /META-INF/applicationContext.xml
> - this specifies the properties required to enable annotation  
> processing and auto detection.  Change com.xyz in base-package to the  
> base package (and subpackages) to be searched for annotations.
> 
> <?xml version="1.0" encoding="UTF-8"?>
> 
> <beans xmlns="http://www.springframework.org/schema/beans"
>         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>         xmlns:tx="http://www.springframework.org/schema/tx"
>         xmlns:aop="http://www.springframework.org/schema/aop"
>         xmlns:context="http://www.springframework.org/schema/context"
>         xsi:schemaLocation="http://www.springframework.org/schema/ 
> beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
>                             http://www.springframework.org/schema/tx
> http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
>                             http://www.springframework.org/schema/aop
> http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
>                             http://www.springframework.org/schema/context 
>   http://www.springframework.org/schema/context/spring-context-2.5.xsd">
> 
> 	<!-- auto discover annotated classes -->
> 	<context:component-scan base-package="com.xyz" />
> 	
> 	<!-- support annotated classes and properties -->
> 	<context:annotation-config/>
> 
> </beans>
> 
> Step 2:
> 
> Start application and spring application context
> 
>     public static void main(String[] args)
>          throws Exception
>      {
>          // load and start spring
>          ApplicationContext context = new ClassPathXmlApplicationContext
>          (
>              new String[] { "/META-INF/applicationContext.xml" }
>          );
> 
> 	// load server
> 	MyServer server = (MyServer) context.getBean("myServer",  
> MyServer.class);
> 	server.start();
>      }
> 
> Step 3:
> 
> Define server as a spring bean responsible for setting up Netty.
> 
> @Component
> public class MyServer
> {
>      @Autowired
>      private MyServerPipelineFactory _pipelineFactory;
> 
>      private Channel _server;
> 
>      public MyServer()
>      {
>          super();
>      }
> 
>      public void start()
>      {
>          // configure factory
>          ChannelFactory factory = new NioServerSocketChannelFactory
>          (
>              Executors.newCachedThreadPool(),
>              Executors.newCachedThreadPool()
>          );
> 
>          // configure pipeline factory and bootstrap
>          ServerBootstrap bootstrap = new ServerBootstrap(factory);
>          bootstrap.setPipelineFactory(this._pipelineFactory);
>          // bootstrap.setOption("child.tcpNoDelay", true);
>          // bootstrap.setOption("child.keepAlive", true);
> 
>          // bind and start to accept incoming connections
>          this._server = bootstrap.bind(new InetSocketAddress(TCP_PORT));
>      }
> 
> Step 4:
> 
> Define the custom pipeline factory for creating the relevant handlers.
> 
> @Component
> public class MyServerPipelineFactory implements ChannelPipelineFactory
> {
>      @Autowired
>      private MyRequestHandler _handler;
> 
>      public ChannelPipeline getPipeline() throws Exception
>      {
>          // create a default pipeline implementation
>          ChannelPipeline pipeline = Channels.pipeline();
> 
> 	// setup whatever encoders/decoders you need
>          pipeline.addLast("decoder", new StringDecoder());
>          pipeline.addLast("encoder", new StringEncoder());
> 
> 	// add processing handler (auto-injected via spring)
>          pipeline.addLast("handler", this._handler);
> 
> 	// return pipeline
>          return pipeline;
>      }
> 
> }
> 
> Step 5:
> 
> Define the processing handler to handle business logic
> 
> @Component
> @ChannelPipelineCoverage(ChannelPipelineCoverage.ALL)
> public class MyRequestHandler extends SimpleChannelUpstreamHandler
> {
>      // inject other spring beans as you need
>      @Autowired
>      private OtherSpringBeans _otherSpringBean;
> 
>      @Override
>      public void exceptionCaught(ChannelHandlerContext ctx,  
> ExceptionEvent event)
>          throws Exception
>      {
>          event.getCause().printStackTrace();
>          event.getChannel().close();
>      }
> 
>      @Override
>      public void messageReceived(ChannelHandlerContext ctx,  
> MessageEvent event)
>          throws Exception
>      {
>          // handle event and its object (ie: string for string decoder)
>          // use any autowired beans to perform logic against it
>      }
> }
> 
> That is the basic path I follow.  Now I can easily add and inject  
> beans by simply declaring a class, marking it as a spring @Component,  
> and then adding the @Autowire to the class.  I have been doing this  
> for a few different projects now and it is extremely beneficial.  For  
> example, it allows you to change implementations by creating a  
> different @Component instance.
> 
> The problem with this approach though is that as the handler is  
> injected into a singleton class, the handler is also a singleton.   
> Thus, you cannot do a stateful handler that is request specific.   
> There may be a way to do that within Spring, but I have not  
> investigated as I have had no need yet.  Generally, my business logic  
> is not stateful, just the decoders (ie: frame decoder) is stateful and  
> those are manually created in the pipeline.
> 
> Other things you can do as well is inject a list of handlers into a  
> class such as @Autowire List<Handler> _handlers.  In that case, Spring  
> will find every @Component that implements Handler and inject as a  
> list.  Then, just add each of those handlers to the pipeline.  Using  
> this approach, you can add handlers automatically to a pipeline by  
> merely creating a new class and marking it as a @Component.  That  
> really simplifies and abstracts the pipeline.  The problem here is  
> that there is no order defined for the handlers in the list and the  
> order generally matters in the pipeline.  You could solve that by  
> providing some annotation and processing that annotaiton while  
> building the pipeline.  Alternatively, you could mark the handlers as  
> Comparable and then use a sorted list letting the handlers compare  
> against themselves (maybe using some order constant defined in each  
> class).
> 
> Anyways, if you need further help or understanding, let me know.
> 
> Thanks,
> 
> =================================
> Nicholas Hagen
> Software Engineer
> www.znetdevelopment.com
> =================================
> Coming Soon:  Push RSS
> RSS Viewer (Push) for iPhone OS 3
> www.znetdevelopment.com/znet/iphone.html
> =================================
> 
> On Aug 19, 2009, at 3:18 PM, Nicholas Hagen wrote:
> 
>> I have examples I'll forward to the list later tonite.
>>
>> Nicholas Hagen
>> Software Engineer
>> www.znetdevelopment.com/blogs
>> * sent from my iPhone *
>>
>> On Aug 19, 2009, at 1:51 PM, Simon James <sjames at btisystems.com>  
>> wrote:
>>
>>>
>>>
>>> Are there any documented examples of how to use Spring to create and
>>> bind a
>>> pipeline for a simple standalone server, for example like the
>>> TimeServer in
>>> the user guide?
>>>
>>> I apologize if this is not the appropriate place for this question.
>>> I have
>>> searched the forums and other online resources, but failed to find
>>> anything
>>> specific.
>>> -- 
>>> View this message in context:
>>> http://n2.nabble.com/Newbie%3A-Netty---Spring-tp3474198p3474198.html
>>> Sent from the Netty User Group mailing list archive at Nabble.com.
>>> _______________________________________________
>>> netty-users mailing list
>>> netty-users at lists.jboss.org
>>> https://lists.jboss.org/mailman/listinfo/netty-users
>> _______________________________________________
>> netty-users mailing list
>> netty-users at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/netty-users
> 
> 
> _______________________________________________
> netty-users mailing list
> netty-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/netty-users
> 
> 

-- 
View this message in context: http://n2.nabble.com/Newbie%3A-Netty---Spring-tp3474198p3477265.html
Sent from the Netty User Group mailing list archive at Nabble.com.


More information about the netty-users mailing list