EJB working principle learning notes
1 RMI working principle 2 WebSphere implementation 3 WebLogic implementation 4 understanding
1: RMI works first talk about RMI's working principle, because EJB is based on RMI after all. There is not much nonsense, and the nature of RMI is achieved between different JVMs.
The implementation method that calls it is to open a STUB and SKELETON in two JVMs, both of which communicate the parameters and return values via Socket communication.
There are a lot of examples of the RMI to find a lot, but most of them are implemented by extende interface java.rmi.remote.
The package is very complete, it is inevitable to make people feel the feeling of flowers in the fog. The following example is I saw in "Enterprise Javabeans", though
It is rough, but it is very intuitive, which is good to learn about its working principle.
1. Define a Person interface, two business methods, getage () and getname ()
Code:
Public Interface Person {public int getage () throws throwable; public string getname () throws throwable;
2. Person's implementation PersonServer class code:
Public Class Personserver Implements Person {Int Age; String Name
Public Personserver (String Name, Int Age) {this.age = age;}
Public int getage () {returnid
Public string getname () {return name;}}
3. Ok, we now want to call Getage () and getName () in the Client machine.
Method, then you have to write the corresponding Stub (Client) and the Skeleton (Server) program. This is the implementation of Stub: Code:
Import java.io.objectOutputStream; import java.io.objectInputStream; import java.net.socket;
Public Class Person_stub IMPLEments Person {Socket Socket;
Public person_stub () throws throwable {// connect to skeleton socket = new socket ("computer_name", 9000);}
public int getAge () throws Throwable {// pass method name to skeleton ObjectOutputStream outStream = new ObjectOutputStream (socket.getOutputStream ()); outStream.writeObject ( "age"); outStream.flush ();
ObjectInputStream inStream = new ObjectInputStream (socket.getInputStream ()); return inStream.readInt ();} public String getName () throws Throwable {// pass method name to skeleton ObjectOutputStream outStream = new ObjectOutputStream (socket.getOutputStream ()); outStream .writeObject ("name"); outstream.flush ();
ObjectInputStream Instream = New ObjectInputStream (Socket.getInputStream ()); Return (String) Instream.ReadObject ();}}
Note, Person_stub and PersonServer, all imports
Person. They all achieve both business () and getname ().
Method, different is that PersonServer is real implementation, and Person_STUB is to create a socket connection and send a request to Skeleton, then pass
Skeleton calls the Personserver method, and finally receives the result of the return.
4. Skeleton implements code:
Import java.io.objectOutputStream; import java.io.objectInputStream; import java.net.socket; import java.net.serversocket;
Public Class Person_skeleton Extends Thread {Personserver MyServer;
Public Person_Skeleton (Personserver Server) {// Get Reference OF Object Server this.myserver = Server;}
Public void run () {Try {// new socket at port 9000 Serversocket Serversocket = New ServerSocket (9000); // Accept stub's request socket socket = serversocket.accept ();
While (socket! = null) {// get stub's request ObjectInputStream Instream = New ObjectInputStream (Socket.getInputStream ()); string method = (string) instream.readObject ();
// check method name if (method.equals ( "age")) {// execute object server's business method int age = myServer.getAge (); ObjectOutputStream outStream = new ObjectOutputStream (socket.getOutputStream ()); // return result To Stub Outstream.writeInt (age); outstream.flush ();
if (method.equals ( "name")) {// execute object server's business method String name = myServer.getName (); ObjectOutputStream outStream = new ObjectOutputStream (socket.getOutputStream ());
// Return Result to Stub outstream.writeObject (Name); outstream.flush ();}}} catch (throwable t) {T.PrintStackTrace (); system.exit (0);}}
Public static void main (string args []) {// new object server personServer Person = New Personserver ("Richard", 34);
Person_skeleton skel = new person_skeleton (perscl.start ();}}
Skeleton class Extends from Thread, it is standing in the background and receives the Request sent by the client at any time. And according to the send
Key to call the corresponding business method.
5. Last, Client's implementation code:
Public Class Personclient {public static void main (string [] args) {try {person Person = new person_stub (); int Age = person.getage (); string name = person.getname (); system.out.println (name "IS" AGE "YEARS OLD");} catch (throwable t) {T.PrintStackTrace ();}}} Client's essence is that it must know the definition of the Person interface, and instance a person_stub, come through stub Call Business Method,
As for how Stub is going to communicate with Server, the Client does not have to manage.
Pay attention to it: persists: Person Person = New Person_stub (); not Person_Stub Person = New Person_stub ();
why? Because it is necessary to facilitate interface programming, huh, huh.
2: WebSphere implements EJB class list here to talk about the call relationship of each class here for WebSphere.
Assume that we have to create a sessionbean read User information, we need to write 3 files: 1. UserviceHome.java Home interface
2. Uservice.java Remote Interface
3. UserServiceBean.java bean implementation
WSAD will eventually generate 10 Class. What is the other 7? Let's take a number of:
4. _USERSERSERVICEHOME_STUB.JAVA This is of course a Home interface in the Client side (dynamically loaded) Stub class, it is IMPLEments UserviceHome.
5. _ejsremotestatelessuserServiceHome_A940AA04_TIE.JAVA HOME interface in the SKELETON class in the Server side, "A940AA04" should be randomly generated, all other related class names will have this logo
Strings, TIE is called Corba's called Skeleton.
6. EJSREMOTASTATASSERSERSERVICEHOME_A940AA04.Java Home Interface Implementation in Server end, of course, it also imports UserviceHome.
7. EJSSTATASSERSERSERVICEHOMEBEAN_A940AA04.JAVA is called by # 6, Create _userService_stub. (Why can't # 6 can't directly create _USERSERVICE_STUB? Next, then.)
8. _USERSERSERVICE_STUB.JAVA Remote Interface The stub class of the Client side (dynamically load). It imports Uservice.
9. _ejsRemotestateLessuserService_a940aa04_tie.java Remote Interface The Skeleton class in the Server end.
10. EJSREMOTESTATELESSUSERSERVICE_A940AA04.Java Remote Interface Implementation in the Server end, of course, it is also imports Uservice. Also, it is responsible for calling UserServiceBean - that is, the bean we wrote bean implementation class - the business method inside.
So, what is the call relationship between the various classes? Simply put, it is two RMI cycles. First RMI cycle first to see how the client's program is written:
Code:
Try {INIALCONText CTX = New InitialContext ();
// First Step UserviceHome Home = (userServiceHome) PortableRemoteObject.narrow (CTX.lookup (JNDISTRING), UserServiceHome.Class;
// Home: _USERSERSERVICEHOME_STUB System.out.println (Home.toString ());
// Second steps Uservice Object = home.create ();
// OjBect: _USERSERVICE_STUB System.out.println (Object.toString ());
// Step 3 INT userid = 1; UserInfo Ui = Object.getuserInfo (userID);
After the first step, we got a userServiceHome (interface) defined object Home, then which Class is from HOME.
What about INSTANCE? Look with Debug, I know that HOME is originally _USERSERSERVICEHOME_STUB instance.
From the second step, we are concerned, although there is only a simple line of code, users.create (); but what is the system behind it? Let's take a look at the code:
1. Call home.create () code:
UserServiceHome Home; Uservice Obj = Home.create ();
2. It is actually called _USERSERSERVICEHOME_STUB.CREATE (), in this method, Stub sends a CREATE string to Skeleton
: Code:
Org.omg.corba.portable.outputStream out = _REQUEST ("Create", true); in = (org.omg.corba_2_3.portable.inputstream) _invoke (OUT)
3. The SKELETON of the Server terminal receives the Request sent by Stub and calls the corresponding method: Code:
_EjsremotestatelessuserServiceHome_A940AA04_tie._invoke () {... Switch (Method.Length ()) {Case 6: IF (Method.equals ("create")) {Return Create (in, reply);} ..... }
Code:
_EJSRemoteStatelessUserServiceHome_a940aa04_Tie.create () {EJSRemoteStatelessUserServiceHome_a940aa04 target = null; result = target.create (); org.omg.CORBA.portable.OutputStream out = reply.createReply (); Util.writeRemoteObject (out, result); return out;} 4 . Skeleton calls the CREATE method code for the Server end of UserServiceHome:
EJSREMOTELESSUSERSERVICEHOME_A940AA04.CREATE () {userService _ejs_result; _ejs_result = EJSSTATASSUSERSERSERVICEHOMEBEAN_A940AA04.CREATE ()
5. # 4 calls EJSSTATASSERSERSERVICEHOMEBEAN_A940AA04.CREATE () code:
Uservice result = super.createwrapper (new beanid (this, null);
At this point, we finally ended the first RMI loop and got the Remote Interface Uservice's Stub class _USERSERVICE_STUB, that is, # 5
Rest in it.
Here is a problem, why # 4 does not directly create _USERSERVICE_STUB, and turn a # 5 hand? Because # 4 extends from
EJSWRAPPER, it has no ability to create stub, so you must use the # 5, Which Extends from ejshome, you can generate one
STUB. If not to generate this stub, you should not leave # 5. Second RMI cycle OK, NOW We got the object Which is instanceof _userService_stub, and imports USERSERVICE
Now our Client ends go to the third step: userinfo ui = Object.getuserinfo (userID);
Continue to see the code, start the second RMI loop:
1. Call Object.getUserInfo () code:
Uservice Object; Object.getUserInfo (UserID);
2. Actually call _USERSERVICE_STUB.GETUSERINFO (INT)
Arg0), in this method, Stub sends a getUserinfo string and arg0 parameters to Skeleton:
Code:
Org.omg.corba.portable.outputStream out = _Request ("getuserinfo", true); out.write_long (arg0); in = (org.omg.corba_2_3.portable.inputstream) _invoke (out);
3. The SKELETON of the Server terminal receives the Request sent by Stub and calls the corresponding method: Code:
_EJSRemoteStatelessUserService_a940aa04_Tie._invoke () {switch (method.charAt (5)) {case 83: if (method.equals ( "getUserInfo")) {return getUserInfo (in, reply);} ......}} _EJSRemoteStatelessUserService_a940aa04_Tie. getUserInfo () {EJSRemoteStatelessUserService_a940aa04 target = null; int arg0 = in.read_long (); UserDTO result = target.getUserInfo (arg0); org.omg.CORBA_2_3.portable.OutputStream out = reply.createReply (); out.write_value (result Userdto.class; return out;}
4. Skeleton calling the server-end implementation class of the servervice server implementation:
EJSREMOTESTATASSUSERVICE_A940AA04.GETUSERINFO () {UserServiceBean_ejs_beanref = container.preinvoke (this, 0, _ejs_s); _ejs_result = _ejs_beanref.getuserinfo (ID);}
The last final, # 4 finally called the getUserInfo method in the UserServiceBean we wrote, this is what we really want to do.
.
At this point, the second RMI cycle is finally ended. The call flow chart reviews the above analysis, it can be clearly seen the process of the two RMI loops, the following picture (see link) describes the entire process:
http://www.pbase.com/image/27229257
Yellow 1, 6, 10 is to write by the programmer, and the rest is the system generated.
# 1 is home interface, # 2, and # 4 are both IMPLEMENTS. # 6 is Remote Interface, # 7, and # 9 all imports. # 10 is a bean implementation. 3: WebLogic implementation a remote object at least 4 Class files: remote object; the interface of the remote object; the STUB of the object of the remote interface;
Leton's 4 Class files.
In EJB, at least 10 CLASS:
Bean class, a bean implementation class for specific APP Server
BEAN's Remote interface, Remote interface of a particular app server implementation class, specific app
Server's Remote interface implementation class STUB class and Skeleton class
BEAN's Home interface, HOME interface for specific App Server implementation class, specific APP
Server's Home interface implementation class Stub class and Skeleton class
Unlike RMI, this 10 CLASS in EJB really requires only three written, namely the bean class and its Remote interface, HOME interface
As for other seven CLASSs, how is it generated, where is packaged, or if more types of files need to be used, depending on the APP
Server exhibits a relatively large difference and cannot be generalized.
Take WebLogic, WebLogic's bean implements classes, as well as the three interface of WebLogic's implementation class being packaged to EJB when EJBC
The JAR package is inside, these 3 Class files can be seen. And the home interface and the implementation of WebLogic's implementation of the Type of STUB, Skeleton
The class is when the EJB is deployed to WebLogic, generated by the web class and the Skeleton class by WebLogic, so these 4 classes are not seen.
file.
For a client remote call EJB, you should pass multiple RMI loops in two remote objects. The first is to find the Home interface through JNDI, get Home
The implementation class of the interface, this process is actually quite complicated, first to find the WEBLOGIC implementation class for the HOME interface, then create an HOME interface Web
Logic implements the object instance of the STUB class of the class, sequentially transmitted to the client (note that the instance of the Stub class is in the first RMI loop, by the service
The gear is sent to the client, so it is not necessary to save the client's WebLogic implementation class's Stub class), and finally the client gets the STU.
Class B object instance (ordinary RMI needs to save the Stub class on the client, and EJB does not need, because the server will send the STUB class's object instance to
Client).
After the client gets the server to the WEBLOGIC implementation of the WEBLOGIC implementation class, the client is called the Create method of the Stub class.
The code is home.create (), but the background is going to do a lot of things), so through the second RMI loop, on the server side, HOME interface WebLogic
Implementing the class's Skeleton class After receiving the call information of the STUB class, it will call the Create method for the WEBLOGIC implementation class of the Home interface.
On the server, the desk of the home interface WebLogic implementation class's Create method to call the bean class's WebLogic implementation class EJBCREATE method, in service
Serving or assign an EJB instance, then sequence the STUB class object instance of the WebLogic implementation of the remote interface of this EJB instance
Give the client.
The client receives the object instance of the STUB class for the WebLogic implementation class of the Remote Interface, and the method of the object instance is called (in the client code.
In the case of the call to the Remote interface), the Skeleton class object that is transmitted to the server-side Remote interface, and Skele
TON class object calls the WebLogic implementation class of the corresponding Remote interface, then the WebLogic implementation class of the Remote interface will then call the bean class WE
The blogic implements the class, so that the remote call of the EJB object is completed.
After reading a post, I didn't say it too clearly. Since I wrote post, I would like to completely clear it.
Take ordinary RMI, there are 4 CLASS, which are remote objects, objects interface, object's Stub class, and Skeleton classes. And the object itself and the right
At the same time, the STUB class implemented the interface class. And when we call the remote object in the client code, although the interface is manipulated in the code, it is essentially
Is in manipulating the Stub class, for example:
Interface class: hello
Remote object: Hello_Server
Stub class: Hello_STUB
Skeleton Class: Hello_skeleton
Client code to write this:
Hello H = new hello_stub (); h.getstring (); we will not write this:
Hello_stub h = new hello_stub (); h.getstring ();
Because the use interface is applicable, even if the interface is replaced, you do not need to change the code. Therefore, the client needs Hello.class and Hello_
Two files of Stub.class. But for EJB, hello_stub.class is not required because the server will send it, but hello.
The Class file client is invalid, there must be. On the surface, our client code is manipulating Hello, but don't forget that hello is just an interface.
Abstract, essentially in manipulating hello_stub.
Take the EJB on WebLogic Example, 10 Classs are:
Bean Class: Hellobean (User Writing) Bean WebLogic Implementation Class: Hellobean_Impl (EJBC Generation) Home Interface: HelloHome (User Writing) Home Interface WebLogic Implementation Class (Hello Bean) _ HomeImpl (EJBC Generated) Home Interface WebLogic Implementation The STUB class (HELLO bean) _ HomeImpl_wlstub (Dynamically generated by a Dynamic Biode) home interface WebLogic implementation class Skeleton class (Hello Bean) _ HomeImpl_WLSkeleton (Dynamically generate byte code when deploying
Remote Interface: Hello (User Writer) Remote Interface WebLogic Implementation Class ((Hello Bean)) _ EOIMPL (EJBC Generated) Remote Interface WebLogic Implementation Class STUB class (Hello Bean) _ EOIMPL_WLSTUB (dynamically generated byte when deploying Code) Remote Interface WebLogic Implementation Class's Skeleton class (Hello bean) _ EOIMPL_WLSKELETON (dynamically generated by node code)
)
The client only needs both files of hello.class and hellohome.class.
((Hello Home) Home = (("(CTX.lookup (" Hello "), ((Hello)
HOME)). Class);
This line of code is a Home interface from JNDI, but please remember! The interface is abstract, then how the home is the object instance
? Very simple, use the toString () output to look at it, the following line is the output:
((Hello Bean) _ HomeImpl_wlstub @ 18C458
This indicates that Home is actually an instance of the Hellobean_HomeImpl_wlstub class by looking for the object obtained from the server's JNDI tree.
Next, client code:
Hello h = home.create ()
The same hello is just an abstract interface, then what is the H object? Print:
(Hello Bean) _ EOIMPL_WLSTUB @ 8fa0d1
It turned out to be an object instance of Hellobean_eoImpl_wlstub.
Use this example to briefly describe an EJB call process:
First of all, the client JNDI query, the server JNDI tree actually binds the object that is hellobean_homeimpl_wlstub, so the server will create an object instance of Hellobean_homeImpl_wlstub, serialization returns to the client.
So the client gets the HOME object, the surface is an instance of the HelloHome interface, which is actually a remote call to get HelloBea.
N_HomeImpl_wlstub class object instance, don't forget that Hellobean_HomeImpl_wlstub also implements the HelloHome interface.
Then home.create () is essentially hellobean_homeimpl_wlstub.create (), which will send information to Hellobean_Homeim
Pl_wlskeleton, and hellobean_homeimpl_wlskeleton accepts information, then call Hellobean_HomeImpl's Create Party
The method, the first complete RMI cycle is completed.
Note that during this RMI loop, the remote object is Hellobean_HomeImpl, the interface of the remote object is HelloHome, the object's stub is HEL.
Lobean_HomeImpl_wlstub, the object's Skeleton is Hellobean_HomeImpl_wlskeleton.
Then hellobean_homeimpl then calls the Hellobean_Impl's EJBCREATE method, and the EJBCREATE method of Hellobean_Impl will be negative
Responsible to create or assign a bean instance and create an object instance of Hellobean_eoImpl_wlstub.
This step is more interesting that in the previous RMI loop, the remote object hellobean_homeimpl is a proxy Hellobean_ho in the client.
MeiMPL_WLSTUB, but in this step, hellobean_homeimpl acts as a proxy class of Hellobean_Impl, but hellobean_
HomeImpl is not in the client, but is on the server, there is no RMI.
Then hellobean_eoimpl_wlstub's object instance is sequenced to the client, this step is also very interesting, the last RMI process, the protagonist is Hello
Bean_HomeImpl and its proxy Hellobean_HomeImpl_wlstub, but this time it replaced with Hellobean_eoImpl and its proxy class h
Ellobean_eoimpl_wlstub is playing.
Hello h = home.create (); h.helloworld ();
Suppose the Hello interface has a HelloWorld remote method, then the helloWorld method in which the Hello interface is called, it is actually tune.
HelloBean_eoimpl_wlstub's HelloWorld method.
The HelloBean_eoImpl_wlstub's HelloWorld method will then send information to hellobean_eoimpl_wlskeleton on the server, and H
Ellobean_eoImpl_wlskeleton After receiving the information, then call the HelloBean_eoImpl's HelloWorld method. At this point, complete the second time
Complete RMI loop process.
In just now hellobean_eoimpl is called as a remote object, its proxy class is hellobean_eoimpl_wlstub, but now Hellobea
n_eoimpl is a proxy class that is Hellobean_Impl. Now hellobean_eoimpl went to call the HelloBean_Impl's HelloWorld method. note! Hellobean_impl inherits Hellobean, and HelloWorld method in Hellobean is the code we personally prepared, now finally
The code we wrote!
At this point, the EJB call process is finally completed. During the whole process, the class mainly want to call is Hellobean_Impl, Hello
Bean? _HomeImpl, Hellobean_HomeImpl_wlskeleton, hellobean_eoimpl, hellobean_eoimpl_wlskeleton. customer
The class mainly called by the house is Hellobean_HomeImpl_wlstub, hellobean_eoimpl_wlstub, these two classes are not in the client code
Will appear directly, the class in the code is their interface hellohome and hello, so the client needs these two interface files, and Stub is
The server is delivered to them.
4 It is understood that it will be simply in order to adapt to distributed development.
First, return to the flow chart of my last given. http://www.pbase.com/nobo123/Image/27229257
The most primitive impulse of the client end is certainly able to call directly # 10.UnserviceBean is cool. Then the first question is coming, Client and Server are not in a JVM.
This is good, don't we have RMI, well, this problem is so solved: 1. UserviceBeaninterface.getuserInfo () 2. UserServiceBeansTub 3. UserServiceBeanskeleton 4. UserServiceBean
Used, the second problem is coming, UserServiceBean is only used, no one manages Logic, Security Logic, Bean Instance Pooling logic
The problems that have to be considered have surface.
OK, we think of using a Delegate, EJBOBJECT to do all these logic management. CLIENT and EJBOBJECT deal, EJBOBJ
ECT calls UserServiceBean.
Note that this EJBOBJECT is also an interface, # 6.USERSERVICE This interface is from its extends. And EJBOBJE
These Logic managed by CT is part of the AppServer.
The current process changes to: EJBOBJECT 1. Uservice.getuserinfo () 2. UserServiceStub 3. UserServiceIMP 5. UserServiceBean
This has always been in the # 6, # 7, # 8, # 9, # 10 in the whole map.
Can we meet our needs now? No, the third question came again: Since it is a distributed development, then I certainly have no reason to use only one Specified Server, I may need to use several different server, and
And EJBOBJECT also needs to be managed.
OK, in order to adapt to your needs, we have to add another homeObject, first of all, it will decide which Server (of course, is by you JNDi
String settings, second, it manages EJBOBJECT. Note that this EJBHOME is also an interface, # 1.USERSERVICEHOME This Interface is from it extends. And ejbho
ME Manage EJBObject's Logic, is also part of the appserver.
The current call order is 1. ejbhome.create () 2. EJBHOMESTUB 3. EJBHomeskeleton 4. EjBhomeImp (EJSWrapper) 5. EJSHOME
Get ejbobject
6. UserService.getuserinfo () 7. UserServiceStub 8. UserServiceIMP 10. UserServiceBean
It is now consistent with the order in which the call map is completely and the flowchart.
In summary, EJB calls are really troublesome, but they are so troublesome, it is really a trouble, it is really there.