RMI and Spring
RMI is a way for the Java platform to implement remote invocation, introducing the Java platform to JDK1.1. "Spring simplifies the RMI model and provides a proxy factory Bean that allows us to assemble our RMI services into our Spring applications like local JavaBean." "Here's one more thing, RMI is a way to implement RPC on the Java platform." Considerations for RMI use
The RMI Publishing Service and the invocation service need to specify a port, which means traversing the firewall if necessary to access the extranet.
RMI's service side involves two ports, the registration port and the service port, and the registration port corresponds to the operator of the service, and the service port is the business person the client is really looking for. The registration port defaults to 1099, the service port is randomly assigned, so you need to specify it if you have a firewall.
RMI is java-based, so both the server and the client must be Java developed.
If the client is configured to cache server-side services (that is, the client cachestub=true), then the client call will complain when the side is restarted, with two solutions: one is the client setting is not cached (that is, client Cachestub=false), Another method is to allow a new configuration call (Refreshstubonconnectfailure=true) to be invoked after the cache call fails. So here, it can be understood that RMI remote calls need to establish a channel through the registration port and then access the business through the service port.
If you need to transfer objects in a remote call, you must be aware of the serialization problem of the Java object (the portal). rmi-spring Test Overview
We use three projects to complete the test. API: Defines interface and entity information, and contains abstract methods. Server: Implements interfaces in the API and provides RMI remote services externally. The startup mode starts with the main function. Consumer: A Web project that uses configuration to inject a remote service into a local interface to implement a remote invocation. Master:maven Aggregate parent items for easy clean and install.
API main Code entity class Model.java
Import java.io.Serializable;
public class Model implements serializable{
private static final long serialversionuid = 1L;
Private String userName;
private int age;
Get\set method slightly
}
Interface Apiservice.java
Public interface Apiservice {
string getName (string name);/Enter what, return what
Model Getmodel (); Return entity class-Test Remote Delivery Object
}
Server main codeInterface Implementation Class Apiserviceimpl.java
public class Apiserviceimpl implements apiservice{
@Override public
string GetName (string name) {
SYSTEM.OUT.PRINTLN ("server-side is called");
return name;
@Override Public
Model Getmodel () {
model m=new model ();
M.setusername ("Jecket");
M.setage (a);
return m;
}
}
Spring Bean Registration and remote service configuration
You can configure the Java configuration class with annotations
@Configuration public
class Rpcbean {
/**
* registered as remote service
* @return
/
@Bean
Public Rmiserviceexporter Rmiexporter () {
rmiserviceexporter rmi=new rmiserviceexporter ();
Rmi.setservice (Getapiservice ());//interface implements Spring Bean
rmi.setservicename ("Apiservice");//remote Service name
Rmi.setserviceinterface (Apiservice.class);//Interface
rmi.setregistryport (8080);//Remote service registration Port
Rmi.setserviceport (8082);//remote service business Access port return
rmi;
}
/**
* Registered as spring Bean
* @return * * *
@Bean public
apiservice Getapiservice () {return
new Apiserviceimpl ();
}
Spring Configuration Scan Information
<context:component-scan base-package= "Com.bestcxx.stu.rpc.rmi.bean"/><!--Rpcbean.java where the package road-->
You can also use the configuration method of XML to Spring configuration file contents
<bean id= "Apiservice" class= "Com.bestcxx.stu.rpc.rmi.service.ApiServiceImpl"/> <!--Spring bean-->
<bean id= "Serviceexporter" class= "Org.springframework.remoting.rmi.RmiServiceExporter" > <!--RMI Remote service configuration-->
<property name= "service" ref= "Apiservice"/> <property name= "ServiceName"
Apiservice "/> <property name= serviceinterface" value= "Com.bestcxx.stu.rpc.rmi.api.ApiService"/>
<property name= "Registryport" value= "8080"/><!--registration Port--> <property name=
"Serviceport" value = "8080"/><!--communication port, not specified on random -->
</bean>
Start the Server
public static void Main (string[] args) {
ApplicationContext ctx =
new Classpathxmlapplicationcontext (" Classpath:spring/applicationcontext-bean.xml ");
SYSTEM.OUT.PRINTLN ("server-side start ...");
}
Consumer Main CodeTo set the proxy service for the remote service, register as a local bean
You can use the annotation configuration
Rmi://127.0.0.1:8080/apiservice, 127.0.0.1 is the remote service address, 8080 is the remote service registration port, Apiservice is the remote service name
@Configuration public
class Rpcbean {
@Bean public
Rmiproxyfactorybean Apiservice () {
Rmiproxyfactorybean rmiproxy=new Rmiproxyfactorybean ();
Remote service address, directly specify the specific host, IP, service name
rmiproxy.setserviceurl ("Rmi://192.168.149.1:8080/apiservice");
Rmiproxy.setserviceurl ("Rmi://127.0.0.1:8080/apiservice");
Define the remote service interface, the server is the interface corresponding to the implementation of the remote service
rmiproxy.setserviceinterface (apiservice.class);
Defines whether this configuration
rmiproxy.setcachestub (true) is cached after the first time a remote service is configured;
If the remote call cache configuration error is set to True, allow
Rmiproxy.setrefreshstubonconnectfailure (false) to be called again;
Detects service-side service availability at client startup-the test found that the property did not work
Rmiproxy.setlookupstubonstartup (false);
Return Rmiproxy
}
}
Spring Configuration Scan Information
<context:component-scan base-package= "Com.bestcxx.stu.rpc.rmi.bean"/><!--Rpcbean.java where the package road-->
You can also use the XML configuration
<bean id= "Apiservice" class= "Org.springframework.remoting.rmi.RmiProxyFactoryBean" >
<property name= " Serviceurl "value=" Rmi://192.168.149.1:8080/apiservice "/> <property name=" serviceurl "value=" rmi://
Localhost:8080/apiservice "/>
<property name= refreshstubonconnectfailure" value= "true"/>
< Property Name= "Lookupstubonstartup" value= "false"/> <property name= "Serviceinterface"
Com.bestcxx.stu.rpc.rmi.api.ApiService "/>
</bean>
Controller Layer Call
@RestController public
class HomeController {
@Autowired
private apiservice apiservice;
/**
* Controller access case, Access database according to ID
* @return * * *
@RequestMapping ("/home") public
map<string, Object> Home () {
map<string,object> map=new hashmap<string,object> ();
String Name=apiservice.getname ("Jecket");//Calling the String type argument method
Model M=apiservice.getmodel ();//Calling the object type return parameter method
Map.put ("Result", "success");
Map.put ("name", name);
Map.put ("model", m);
return map;
}
results show
The server is started locally, and the client does not know that the other network environment accesses the service side:
Service-side startup ...
Server-side is invoked
Browser access client
{' Result ': ' Success ', ' name ': ' Jecket ', ' model ': {' userName ': ' Jecket ', ' Age ': 20}}
GitHub Address
Https://github.com/Bestcxy/RPC/tree/master/rmi/master