"Build a wheel"--cicada source analysis

Source: Internet
Author: User

Objective

Two days ago wrote the article "Build a wheel"--cicada (Lightweight WEB framework) "to introduce you to cicada receive a lot of feedback, there are many good suggestions.

At the same time on GitHub also harvested 80 a few small (absolutely not brush. )

Also have a friend hope to have a source code introduction, this article on the current v1.0.1 version to analyze and analyze together.

No mistake, just released to fix a bug, want to try to upgrade to 1.0.1 it.

Technology selection

Generally before a new thing will have a technology selection process, but this is done in an cicada unusually simple.

Because my demand is to provide a high-performance HTTP service, throughout the open source community actually choose not much.

Plus I'm doing Netty related development recently, so I chose it naturally.

At the same time Netty with the HTTP protocol codec, can be very simple and rapid development of an HTTP server. I just need to focus on parameter processing, routing and other business processing.

At the same time Netty is also based on NIO implementation, performance is also guaranteed. For more information about Netty, refer to this section.

The following is a key analysis of each of these processes.

Routing rules

The core of nature is the processing of HTTP handle , corresponding to the HttpHandle class.

Viewing the source code is very easy to see the specific steps, comments are also obvious.

Only the key features are analyzed here.

Consider the requirements first.

First, as an HTTP framework, it's natural for users to have a place to implement business code, just as we write when we use SPRINGMVC controller .

In fact, at that time, three kinds of options were considered:

    • Define annotations like Springmvc, as long as the corresponding annotations are declared I think this is a business class.
    • Students who have used Struts2 should have an impression that the business class Action is configured into an XML, and the business processing class corresponding to the interface is configured on the inside.
    • The same idea, just replace the XML file with a properties configuration file, and write the corresponding relationship in JSON format.

Then you have to analyze the pros and cons of each scheme.

Scenarios two and three are actually XML and JSON comparisons; XML makes the maintainer feel structurally clear, easy to maintain and new.

JSON is not very convenient to handle, and in such a scenario is not used to transmit nature also does not play an advantage.

Finally, considering that the current popular springboot are going to XML, if we make a dependency on XML, it can't keep up with everyone's usage habits.

Thus, an annotated form similar to SPRINGMVC is used.

Since annotations are used, how does the framework know that a user can access an interface to a business class?

So the first step is naturally the need to scan the annotated class all over and put it in a local cache.

This makes it easy for subsequent routing to be positioned.

Routing Policy

One of the core source code in the routeAction method.

First, the annotations used are scanned globally @CicadaAction , and then the corresponding business class is found based on the requested address.

Global Scan Code:

The first is to get all the classes that are customized in the project, and then decide whether to add @CicadaAction annotations.

It is the target class that caches him in a local Map, allowing it to be retrieved directly from the cache at the next visit (the performance is very lossy).

After execution routeAction , you get a real business class type.

Class<?> actionClazz = routeAction(queryStringDecoder, appConfig);

Method of transmitting parameters

After the class type of the business class has been successfully more than half, it is only necessary to reflect the object that generated it and execute the method.

There is a problem before executing the method, how do I pass the parameters?

Given the flexibility, I used the simplest way to MAP.

Therefore, a common Param interface is defined and the Map interface is inherited.

public interface Param extends Map<String, Object> {    /**     * get String     * @param param     * @return     */    String getString(String param);    /**     * get Integer     * @param param     * @return     */    Integer getInteger(String param);    /**     * get Long     * @param param     * @return     */    Long getLong(String param);    /**     * get Double     * @param param     * @return     */    Double getDouble(String param);    /**     * get Float     * @param param     * @return     */    Float getFloat(String param);    /**     * get Boolean     * @param param     * @return     */    Boolean getBoolean(String param) ;}

It encapsulates several basic types of acquisition methods.

Also in the buildParamMap() method, the parameters in the interface are encapsulated in the MAP.

Param paramMap = buildParamMap(queryStringDecoder);

Business execution

Finally, only the business can be executed; Because the class type of the business class has been obtained above, it can be called by reflection.

It also defines a common interface that a business class needs to implement WorkAction , and wants to implement a specific business as long as it is implemented.

The method parameter here is naturally the parameter interface just defined Param .

Since all business classes are implemented WorkAction , they can be defined as objects at reflection time WorkAction .

WorkAction action = (WorkAction) actionClazz.newInstance();WorkRes execute = action.execute(paramMap);

Finally, the built-in parameter map can be passed in.

Response return

There is a request that naturally has to respond, observing that the interface just defined WorkAction can be found to actually define a WorkRes response class.

All of the response data needs to be encapsulated into this object.

This is nothing to say, it is some basic data.

Finally, the responseMsg() response data is encoded as JSON output in the method.

Interceptor Design

Interceptors are also a basic feature of the framework, and are useful for many purposes.

cicadaImplementation principle is very simple, is to WorkAction call a method before the interface executes business logic, and then call another method after execution.

It is also the same idea to define an interface CicadaInterceptor , which has two methods.

Look at the method name naturally can also see the specific role.

A specific invocation is also performed in both methods.

Here's the point to look at the interceptorBefore method.

It also adds a cache, minimizing the reflection operation.

Adapter

This is enough for an interceptor interface, but not all businesses need to implement two interfaces.

Therefore, an adapter is also provided AbstractCicadaInterceptorAdapter .

It implements the interface as an abstract class CicadaInterceptor , so that the subsequent interception service can inherit the selective implementation method of the interface.

Similar to this:

Summarize

v1.0.1Version of the cicada introduction is complete, wherein the principle and source are relatively simple.

A lot of use of reflection and some design patterns, polymorphism and other applications, this area of less experienced friends can refer to.

At the same time, there are many shortcomings, such as the follow-up will consider a more elegant way, the Interceptor is currently written dead, and subsequent use of dynamic agents to implement custom interception.

In fact cicada , only use the weekend two days to do, the bug is certainly not, also welcome everyone on GitHub to mention issue participation.

Finally post the project address:

Github.com/togetheros/cicada

Your point of praise and forwarding is the biggest support.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.