📄 ch12s04.html
字号:
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Client Objects</title><link rel="stylesheet" href="styles.css" tppabs="http://www.huihoo.org/jboss/online_manual/3.0/styles.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets Vimages/callouts/"><link rel="home" href="index.html" tppabs="http://www.huihoo.org/jboss/online_manual/3.0/index.html" title="JBoss 3.0 Documentation"><link rel="up" href="ch12.html" tppabs="http://www.huihoo.org/jboss/online_manual/3.0/ch12.html" title="Chapter 12. Container architecture - design notes"><link rel="previous" href="ch12.html" tppabs="http://www.huihoo.org/jboss/online_manual/3.0/ch12.html" title="Chapter 12. Container architecture - design notes"><link rel="next" href="ch12s17.html" tppabs="http://www.huihoo.org/jboss/online_manual/3.0/ch12s17.html" title="JMX - foundation of JBoss infrastructure"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><table border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img src="jboss.gif" tppabs="http://www.huihoo.org/jboss/online_manual/3.0/jboss.gif" border="0"></td><td rowspan="2" background="gbar.gif" tppabs="http://www.huihoo.org/jboss/online_manual/3.0/gbar.gif" width="100%" align="right" valign="top"><a href="index.html" tppabs="http://www.huihoo.org/jboss/online_manual/3.0/index.html"><img src="doc.gif" tppabs="http://www.huihoo.org/jboss/online_manual/3.0/doc.gif" border="0"></a><a href="ch12.html" tppabs="http://www.huihoo.org/jboss/online_manual/3.0/ch12.html"><img src="toc.gif" tppabs="http://www.huihoo.org/jboss/online_manual/3.0/toc.gif" border="0"></a><a href="ch12.html" tppabs="http://www.huihoo.org/jboss/online_manual/3.0/ch12.html"><img src="prev.gif" tppabs="http://www.huihoo.org/jboss/online_manual/3.0/prev.gif" border="0"></a><a href="ch12s17.html" tppabs="http://www.huihoo.org/jboss/online_manual/3.0/ch12s17.html"><img src="next.gif" tppabs="http://www.huihoo.org/jboss/online_manual/3.0/next.gif" border="0"></a></td></tr><tr></tr></table><div class="section"><a name="d0e7851"></a><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="d0e7851"></a>Client Objects</h2></div></div><div class="section"><a name="d0e7854"></a><div class="titlepage"><div><h3 class="title"><a name="d0e7854"></a>EJBObject and EJBHome</h3></div></div><p>As previously discussed in many EJB resources, an<tt>EJBObject</tt> is an
object that represents a client's view of the Enterprise Java Bean. It is
generated by the container provider. A client never references an ejb bean
instance directly, but rather references the<tt>EJBObject</tt> which implements the
bean remote interface. The <tt>EJBHome</tt> object is very
similar to <tt>EJBObject</tt> in
the sense that it is also generated by the container. Also, it implements
the bean's home interface, which is defined by the bean provider. Rather
than implementing business logic, however, it provides life-cycle
operations on the enteprise beans.</p></div><div class="section"><a name="d0e7871"></a><div class="titlepage"><div><h3 class="title"><a name="d0e7871"></a>Virtual EJBObject - the big picture</h3></div></div><p>
<tt>EJBObject</tt> is more of an abstract idea than a
physical
implementation. So far, we know that
clients are given a remote
handle to EJBObjects, but how is the
EJBObject physically
implemented on the server side? Well,
it is not implemented at all !</p><p>Most EJB servers that are available today are literally implementing
the EJB
specification. That is, for each
logical EJBObject there is one physical EJBObject that
receives requests.</p><p>This approach is very naive and may easily lead to scalability
problems if there are many EJBObjects
alive at any one time.
In addition, this gives a rather
complex structure to the EJB container.</p><p>For example, one can have a finder method that returns an enumeration
of
1.000.000 EJBObjects. Does this mean
that we now have to create 1.000.000
server EJBObject counterparts? This
would be a serious resource drain ! </p><p>In JBoss there is only one physical EJBObject that serves all logical
EJBObjects. That physical EJBObject is
Container. For each EJB type there is
one container object, which plays the
role of EJBObject by wrapping all instances
of a particular EJB type.</p><p>JBoss' approach is superior in many aspects, and it simplifies the
container architecture immensely.
Clients, however, never notice this. They have
something that looks and feels like a
real server EJBObject, but this is merely an
illusion. Behind the scenes there is
only one object (Container) handling all method
invocations. The final result is full
EJBObject conformity.</p></div><div class="section"><a name="d0e7889"></a><div class="titlepage"><div><h3 class="title"><a name="d0e7889"></a>Two flavours of implementation</h3></div></div><p>JBoss's client objects (<tt>EJBObject</tt> and<tt>EJBHome</tt>) are constructed as
dynamic proxies. But before we investigate dynamic proxies, it is
important to notice that there are two different implementations of
dynamic proxies, that are in fact almost totally the same. The package
jrmp13.interfaces* contains default implementation of<tt>EJBObject</tt> proxies that utilizes the core java.lang.reflect package of j2se 1.3.
In contrast, the package jrmp12.interfaces* contains<tt>EJBObjects</tt> proxies
that are using JBoss's home brewed proxy framework of j2se 1.2.
This package is primarly intended to serve for "history proofing"
of JBoss (i.e., enabling JBoss to be used with j2se 1.2 version).</p><p>*Full package names are:</p><p>
<tt>org.jboss.ejb.plugins.jrmp13.interfaces</tt>
</p><p>
<tt>org.jboss.ejb.plugins.jrmp12.interfaces</tt>
</p></div><div class="section"><a name="d0e7918"></a><div class="titlepage"><div><h3 class="title"><a name="d0e7918"></a>Relation to ContainerInvoker</h3></div></div><p> The ContainerInvoker component, which we will focus on in detail
later,
is responsible for maintaining <tt>EJBObject</tt> and<tt>EJBHome</tt>. A closer look
at <tt>ContainerInvoker</tt> reveals an interface for
obtaining these objects.
Dynamic proxies of <tt>EJBObject</tt> and<tt>EJBHome</tt> are created in<tt>JRMPContainerInvoker</tt>,
a default implementation of the <tt>ContainerInvoker</tt>interface.</p></div><div class="section"><a name="d0e7944"></a><div class="titlepage"><div><h3 class="title"><a name="d0e7944"></a>Dynamic proxies</h3></div></div><p>A dynamic proxy is an object that implements a list of interfaces
specified at runtime when the object is created. A proxy interface
is an interface that is implemented by a proxy class. Each proxy
class instance has an associated invocation handler object, which
implements the interface InvocationHandler. </p></div><div class="section"><a name="d0e7949"></a><div class="titlepage"><div><h3 class="title"><a name="d0e7949"></a>EJBObject as a dynamic proxy</h3></div></div><p>EJBObject and EJHome object are created by following classical
proxy instantiation technique:</p><p>
<pre class="programlisting">Proxy.newProxyInstance(bean.getRemoteClass().getClassLoader(),
new Class[] { bean.getRemoteClass() },
new EntityProxy());</pre>*</p><p>*Not exactly as is, simplified to a certain degree</p><div class="section"><a name="d0e7961"></a><div class="titlepage"><div><h4 class="title"><a name="d0e7961"></a>What do we need to create a client proxy ?</h4></div></div><p>In this particular case, given the classloader that loaded
the entity bean's remote interface, its Class class, and the invocation
handler (<tt>EntityProxy</tt>), we are able to create a new
Proxy instance
which implements the bean's remote interface. Since<tt>java.lang.reflect.Proxy</tt> class is serializible, it can be sent to the remote client across
the network.</p></div><div class="section"><a name="d0e7972"></a><div class="titlepage"><div><h4 class="title"><a name="d0e7972"></a>Relation between proxy and invocation handler</h4></div></div><p>The remote client, having a dynamic proxy class that implements
the bean's remote interface, dispatches all method invocation on that
interface to the instance of the underlying invocation handler.</p></div><div class="section"><a name="d0e7977"></a><div class="titlepage"><div><h4 class="title"><a name="d0e7977"></a>EJB proxy types</h4></div></div><p>Depending on the type of the EJB bean on the server, there are four
proxy classes: <tt>EntityProxy</tt>,<tt>HomeProxy</tt>,<tt>StatelessSessionProxy</tt> and <tt>StatefulSessionProxy</tt>.</p><p>All four proxies implement the<tt>java.lang.reflect.InvocationHandler</tt> interface and also subclass <tt>GenericProxy</tt>, which in
turn contains a
stub of the <tt>ContainerRemote</tt> interface implementor
from the server side.
That implementor is <tt>JRMPContainerInvoker</tt>.</p></div></div><div class="section"><a name="d0e8008"></a><div class="titlepage"><div><h3 class="title"><a name="d0e8008"></a>Invoke method</h3></div></div><p>Each of the proxy classes implements the only method defined
in the <tt>InvocationHandler</tt> interface: invoke.
The invoke method intercepts all calls to the EJB remote
interface (client side) and depending on the particular type of EJB
method, does one of the following:</p><p>- handles the method locally in the <tt>Proxy</tt> class
- passes the method call accross the wire to the remote EJB container
- invokes the method in the local EJB container</p></div><div class="section"><a name="d0e8021"></a><div class="titlepage"><div><h3 class="title"><a name="d0e8021"></a>Advantages</h3></div></div><p>This design of client objects gives maximum flexibility in the
following sense: all calls that can be handled by clients themselves
are handled locally, preventing the roundtrip across the wire and
saving the container from unneccessary loading. Calls coming from other
EJBs, but local to the JVM, are also optimized since they bypass the network
transport layer and call the specific underlying container directly.
Finally, only calls that absolutely must leave the local VM are passed
across the wire.</p></div><div class="section"><a name="d0e8026"></a><div class="titlepage"><div><h3 class="title"><a name="d0e8026"></a>Closing the first half of the circle</h3></div></div><p>Let's trace the remote call on busines method B of an entity
bean.</p><p>First, the method call goes on the proxy interface where it is
dispatched to its invocation handler, which in this case is EntityProxy.
Entity proxy converts the call into a<tt>RemoteMethodInvocation</tt>object and stuffs it
into a <tt>MarshalledObject</tt>. Using a stub of the<tt>JRMPContainerInvoker</tt>, the remote
call is sent over the "wire" to the server's<tt>JRMPContainerInvoker</tt> object
where it is unpacked from <tt>MarshalledObject</tt> and handed
off to the container.</p><p>*Note that, since the jdk1.2 release, skeletons are avoided on the
server side. Consult RMI specification for more info.</p></div></div><table border="0" cellpadding="0" cellspacing="0" height="65"><tr height="65"><td rowspan="2"><img src="gbar.gif" tppabs="http://www.huihoo.org/jboss/online_manual/3.0/gbar.gif" width="432" height="79"></td><td rowspan="2" background="gbar.gif" tppabs="http://www.huihoo.org/jboss/online_manual/3.0/gbar.gif" width="100%" align="right" valign="top"><a href="index.html" tppabs="http://www.huihoo.org/jboss/online_manual/3.0/index.html"><img src="doc.gif" tppabs="http://www.huihoo.org/jboss/online_manual/3.0/doc.gif" border="0"></a><a href="ch12.html" tppabs="http://www.huihoo.org/jboss/online_manual/3.0/ch12.html"><img src="toc.gif" tppabs="http://www.huihoo.org/jboss/online_manual/3.0/toc.gif" border="0"></a><a href="ch12.html" tppabs="http://www.huihoo.org/jboss/online_manual/3.0/ch12.html"><img src="prev.gif" tppabs="http://www.huihoo.org/jboss/online_manual/3.0/prev.gif" border="0"></a><a href="ch12s17.html" tppabs="http://www.huihoo.org/jboss/online_manual/3.0/ch12s17.html"><img src="next.gif" tppabs="http://www.huihoo.org/jboss/online_manual/3.0/next.gif" border="0"></a></td></tr><tr></tr></table></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -