Recently, a system reconfiguration is planned to extract the public parts of multiple systems as a public service, laying the groundwork for future project maintenance and scale-out.
Commonly used service Publishing method has rmi/httpinvoker/hessian/burlap, about these kinds of Java remote Services performance comparison and advantages and disadvantages of all can be consulted: http://www.cnblogs.com/jifeng/archive/ 2011/07/20/2111183.html, this article focuses on how to use custom annotation tags, combined with spring to facilitate the release of services.
One, MAVEN configuration
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.7</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactid>spring-core& lt;/artifactid> <version>3.1.1.RELEASE</version> </dependency> <dependenc Y> <groupId>org.springframework</groupId> <artifactid>spring-context</artifa ctid> <version>3.1.1.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>3.1.1.RELEASE</version> </dependency> <dependency> <g Roupid>org.springframEwork</groupid> <artifactId>spring-webmvc</artifactId> <version>3.1.1.releas e</version> </dependency> <dependency> <groupid>com.caucho</groupid> ; <artifactId>hessian</artifactId> <version>4.0.38</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactid>spring -test</artifactid> <version>3.1.1.RELEASE</version> </dependency> <DEP Endency> <groupId>org.eclipse.jetty</groupId> <artifactid>jetty-webapp</arti Factid> <version>8.1.3.v20120416</version> </dependency>
Second, custom annotation annotation label (remoteservice)
Package Org.springframework.remoting;import Java.lang.annotation.documented;import Java.lang.annotation.elementtype;import Java.lang.annotation.retention;import Java.lang.annotation.retentionpolicy;import Java.lang.annotation.target;import Org.springframework.stereotype.Component; @Target ({elementtype.type}) @Retention (retentionpolicy.runtime) @ Documented@componentpublic @interface remoteservice { servicetype servicetype () default servicetype.http; Class<?> serviceinterface ();}
remoteservice the auxiliary tagRmiserviceproperty, which specifies the port to be published by the RMI service when the RMI service is published.
Package Org.springframework.remoting;import Org.springframework.stereotype.component;import java.lang.annotation. *;import java.rmi.registry.registry;/** * Created by Administrator on 2014/12/8. */@Target ({elementtype.type}) @Retention (retentionpolicy.runtime) @Documented @componentpublic @interface rmiserviceproperty { int registryport () default Registry.registry_port;}
ServiceType, specifying the type of publishing service
Package Org.springframework.remoting;public enum ServiceType { HTTP, BURLAP, HESSIAN, RMI}
Third, define the annotation tag interpreter
public class Serviceannotationbeanpostprocessor extends Instantiationawarebeanpostprocessoradapter implements priorityordered {private int order = ordered.lowest_precedence-1; @Override public Object Postprocessafterinitialization (object bean, String beanname) throws Beansexception {Rem Oteservice service = annotationutils.findannotation (Bean.getclass (), remoteservice.class); Object Resultbean = bean; if (null! = Service) {if (servicetype.http = = Service.servicetype ()) {if (!beanname.startswith ( "/")) {throw new Fatalbeanexception ("Exception initializing Httpinvokerservice for" +beanname+ ", Beanna Me should bean start with \ "/\". "); Httpinvokerserviceexporter httpinvokerserviceexporter = new Httpinvokerserviceexporter (); Httpinvokerserviceexporter.setserviceinterface (Service.serviceinterface ()); Httpinvokerserviceexporter.setservice (Bean); Httpinvokerserviceexporter.afterpropertiesset (); Resultbean = Httpinvokerserviceexporter; } else if (Servicetype.hessian = = Service.servicetype ()) {if (!beanname.startswith ("/")) { throw new Fatalbeanexception ("Exception initializing Hessianservice for" +beanname+ ", beanname should beans start with \" /\"."); } Hessianserviceexporter hessianserviceexporter = new Hessianserviceexporter (); Hessianserviceexporter.setserviceinterface (Service.serviceinterface ()); Hessianserviceexporter.setservice (Bean); Hessianserviceexporter.afterpropertiesset (); Resultbean = Hessianserviceexporter; } else if (Servicetype.burlap = = Service.servicetype ()) {if (!beanname.startswith ("/")) { throw new Fatalbeanexception ("Exception initializing Burlapservice for" +beanname+ ", beanname should beans start with \"/\ " ."); } burlapserviceexporter Burlapserviceexporter = new Burlapserviceexporter (); Burlapserviceexporter.setserviceinterface (Service.serviceinterface ()); Burlapserviceexporter.setservice (Bean); Burlapserviceexporter.afterpropertiesset (); Resultbean = Burlapserviceexporter; } else if (Servicetype.rmi = = Service.servicetype ()) {Rmiserviceexporter Rmiserviceexporter = new Rmiservi Ceexporter (); Rmiserviceexporter.setserviceinterface (Service.serviceinterface ()); Rmiserviceexporter.setservice (Bean); Rmiserviceproperty Rmiserviceproperty = Bean.getclass (). Getannotation (Rmiserviceproperty.class); if (rmiserviceproperty!=null) {Rmiserviceexporter.setregistryport (Rmiserviceproperty.registryport ()); } String serviceName = Beanname; if (Servicename.startswith ("/")) { ServiceName = servicename.substring (1); } rmiserviceexporter.setservicename (ServiceName); try {rmiserviceexporter.afterpropertiesset (); } catch (RemoteException remoteexception) {throw new Fatalbeanexception ("Exception initializing Rmiser Viceexporter ", remoteexception); } Resultbean = Rmiserviceexporter; }} return Resultbean; }/****** Reference accessories ******/}
Iv. Rewriting the spring frameworkannotationconfigutils
Please note that package and class name must be consistent
Package Org.springframework.context.annotation;public class Annotationconfigutils {/****** reference attachment ******//** * Register all relevant annotation post processors in the given registry. * @param registry the registry to operate on * @param source the configuration source element (already extracted) * that T His registration is triggered from. May <code>null</code>. * @return A Set of beandefinitionholders, containing all beans definitions * that has actually been registered by this CAL L */public Static set<beandefinitionholder> registerannotationconfigprocessors (beandefinitionregistry Registry, Object source) {set<beandefinitionholder> beandefs = new Linkedhashset<beandefinitionholder> (4) ; if (!registry.containsbeandefinition (Service_annotation_processor_bean_name)) {rootbeandefinition def = new Ro Otbeandefinition (Serviceannotationbeanpostprocessor.class); Def.setsource (source); Def.setrole (beandefinition. Role_infrastructure); Beandefs.add (Registerpostprocessor (Registry, Def, Service_annotation_processor_bean_name)); }/******* reference attachment *******/return beandefs;} /******* Reference Attachment *******/}
v. Release of services Service Interface
Public interface Httpdateservice {public Date getDate ();}
Publishing services
@RemoteService (Serviceinterface = httpdateservice.class, servicetype = servicetype.http) public class Httpdateserviceimpl implements Httpdateservice { @Override public Date getDate () { return new date (); }}
Spring Base Configuration
<?xml version= "1.0" encoding= "iso-8859-1"? ><beans xmlns= "Http://www.springframework.org/schema/beans" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xmlns:context= "http://www.springframework.org/ Schema/context " xsi:schemalocation=" Http://www.springframework.org/schema/beans/http Www.springframework.org/schema/beans/spring-beans-3.1.xsd Http://www.springframework.org/schema/context Http://www.springframework.org/schema/context/spring-context-3.1.xsd "> <context:annotation-config/ > <!--ID content corresponds to the following service address- <bean id= "/remote/httpdateservice.service" class= " Me.bbvip.springremoting.http.impl.HttpDateServiceImpl "/></beans>
please refer to the attachment for other types of service releases.
Vi. Testing Services
This test uses JUNIT4 with the Spring container test service.
Client Spring Configuration
<?xml version= "1.0" encoding= "iso-8859-1"? ><beans xmlns= "Http://www.springframework.org/schema/beans" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation= "http// Www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd "> <!--Httpinvoker Client,serviceurl corresponds to the above Httpdateserviceimpl ID- <bean id= "Httpdateservice" class= "Org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean" > <property name= "serviceurl" Value= "Http://localhost:8080/remoting/remote/HttpDateService.service"/> <property name= "Serviceinterface" Value= "Me.bbvip.springremoting.http.HttpDateService"/> </bean></beans>
Service test base class, using annotations (runwith/contextconfigurationInitialize the spring container, and before you test the specific logic, publish the project to the jetty container.
@RunWith (Springjunit4classrunner.class) @ContextConfiguration (Locations ={"Classpath:dateservicetest-context.xml "}) public class Serverrunner { private static server server; @BeforeClass public static void Startwebapp () throws Exception { Server = new server (); Connector Connector = new Selectchannelconnector (); Connector.setport (8080); Server.addconnector (connector); Webappcontext webappcontext = new Webappcontext (); Webappcontext.setcontextpath ("/remoting"); Webappcontext.setwar ("Src/main/webapp"); Server.sethandler (webappcontext); Server.start (); System.out.println ("Syetem start sucess."); @AfterClass public static void Stopwebapp () throws Exception { server.stop ();} }
Service Interface Testing
public class Httpdateservicetest extends Serverrunner { @Resource (name = "Httpdateservice") private Httpdateservice Httpdateservice; @Test public void Getgetdate () { System.out.println (new SimpleDateFormat ("Yyyy-mm-dd HH:mm:ss"). Format ( Httpdateservice.getdate ()));} }
Test results:
Syetem Start sucess.2014-12-09 10:43:34
Spring Annotations Release Rmi/httpinvoker/hessian/burlap service