Add a post. Continue to talk about how your annotation is handled.
The main purpose is to add an RPC layer, which provides the service layer and Protocol Resolution layer for transparent RPC calls.
For the service layer, the business logic is concerned. With the Spring AOP principle, the service layer provides
Service. It is not responsible for the processing and conversion of specific RPC protocols. This conversion is injected through the interceptor of the special protocol.
It provides various RPC calls, such as JSON-RPC, XML-RPC, EDI-RPC, and WebService-RPC.
In the service that provides services, you can use the annotation defined by yourself to publish the RPC
Service.
An Enum is defined as the optional value in annotation, and required is used as the value of annontation.
Indicates whether the service and method must be used as the RPC service.
Public Enum required
{
Yes (true), no (false );
Private Final Boolean value;
Required (Boolean value) {This. value = value ;}
Public Boolean value () {return value ;}
}
Define two values: yes, no, and yes. No indicates no
Then define your own Annotation
@ Target ({elementtype. method, elementtype. type, elementtype. Field, elementtype. Parameter
})
@ Retention (retentionpolicy. runtime)
@ Inherited
@ Brief ented
Public @ interface RPC
{
Required required () default required. No;
String name () Default "";
}
The definition here is relatively simple. The name and required attributes are provided. The above elementtype. field, elementtype. parameter can be removed. annotation is similar to a mark made on the class. It is marked on the class. The development of annontation will be described separately in other articles.
Next we will write this annontation processing class. Here I am using spring beanprocesser for annontation parsing. In spring
During runtime, the annotation class of RPC is summarized by scanning all classes.
Add the following content to the spring configuration file:
<Bean class = "com. synchrophy. Framework. Test. annotation. rpcannotationbeanprocessor"/>
<Context: component-scan base-package = "com. synchrophy"/>
In this way, spring will automatically fall into rpcannotationbeanprocessor for processing.
Public class rpcannotationbeanprocessor implements beanpostprocessor, priorityordered
{
Public object postprocessbeforeinitialization (Object bean, string beanname)
Throws beansexception
{
System. Out. println (beanname + "(Before):" + bean );
Class clazz = bean. getclass ();
RPC = (RPC) clazz. getannotation (rpc. Class );
If (RPC! = NULL)
{
Boolean required = rpc. Required (). Value ();
Rpcservicedescription desciption = new rpcservicedescription ();
Try
{
Clazz = Class. forname (clazz. getname ());
}
Catch (exception e ){
Throw new illegalargumentexception (E );
}
String servicename;
If (stringutils. isblank (rpc. Name ()))
{
Servicename = beanname;
}
Else
{
Servicename = rpc. Name ();
}
Desciption. setservicename (servicename );
Desciption. setclazz (clazz );
Method [] MS = clazz. getmethods ();
For (method M: MS)
{
If (! Modifier. ispublic (M. getmodifiers ()))
Continue;
RPC = (RPC) M. getannotation (rpc. Class );
If (required & (RPC = NULL | rpc. Required () = required. Yes ))
| (Required = false & RPC! = NULL & rpc. Required () = required. Yes ))
{
Rpcserviceapideappsapidesc = new rpcserviceapide.pdf ();
Apidesc. setmethod (m );
Apidesc. setmethodname (RPC = NULL | stringutils. isblank (rpc. Name ()))? M. getname (): rpc. Name ());
Class [] PTS = M. getparametertypes ();
Int ind = 0;
For (class PT: PTS)
{
Apidesc. addparameters (IND + "", pt );
IND ++;
}
Desciption. addapis (apidesc );
}
}
System. Out. println ("============= annotation" + desciption );
}
Return bean;
}
Public int getorder ()
{
// Todo auto-generated method stub
Return ordered. lowest_precedence-2;
}
}
In combination with the bean generation process mentioned in the previous article, here we will use this rpcannotationbeanprocessor,
Extended from beanpostprocessor. When beanfactory of the application is processed, two methods defined in the interface are called back.
Here I put annotation processing in the before method, rather than in the after method. This is also determined based on the bean generation process.
Of course, you can also put it in after, and set the prorityorder to higher.
Now we can write a Test Service.
Interface
Public interface beanprocessertestservice
{
Public void test1 ();
Public void Test2 (string name );
}
Implementation
@ Service ("beanprocessertestservice ")
@ RPC ()
Public class beanprocessertestserviceimpl implements beanprocessertestservice
{
/* (Non-javadoc)
* @ See COM. sunvalley. Framework. Test. beanprocessertestservice # test1 ()
*/
@ RPC (required = required. Yes)
Public void test1 ()
{
// Todo auto-generated method stub
System. Out. println ("test1 .........");
}
/* (Non-javadoc)
* @ See COM. sunvalley. Framework. Test. beanprocessertestservice # Test2 (Java. Lang. String)
*/
@ RPC (required = required. Yes, name = "Test2 ")
Public void Test2 (string name)
{
// Todo auto-generated method stub
System. Out. println ("Test2 ........");
}
}
Test
Public class testbeanprocessor extends basetestcase
{
/* (Non-javadoc)
* @ See JUnit. Framework. testcase # setup ()
*/
Protected void setup ()
{
Super. Setup ();
}
Public void testrpcannotation ()
{
Beanprocessertestservice S = (beanprocessertestservice) This. Context. getbean ("beanprocessertestservice ");
System. Out. println (s );
}
}
When loading to context, we can automatically collect the RPC service of beanprocessertestservice,
Both test1 and Test2 have been registered in rpcservice. In this way, various protocols are implemented through protocol layer conversion.
.