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