分享
 
 
 

Jboss源码解析

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

JBoss是一个非常优秀的J2EE的Application Server,研究

它的源代码有助于我们更好的理解J2EE的各种技术。

本系列拟从四个方面分析Jboss源码:

1.EJB Container实现

2.Transaction实现

3.Persistence Mapping

4.Client到Server端的Invocation

-------------------------------------------------------------------

先说第1点:EJB Container实现。

1.1 EJB Pool

我们知道,EJB Container 会维护一个EJB池,

在多个client间共享,避免频繁创建销毁对象的开销。

让我们来看看Jboss实现的Pool:

EJB分EntityBean,MDB,Stateless/Stateful Session Bean,

而Jboss中也对应的有EntityInstancePool,MessageDrivenInstancePool,

StatefulSessionInstancePool,StatelessSessionInstancePool.

让我们先从这4个类的共同基类AbstractInstancePool看起:

class AbstractInstancePool实现了接口InstancePool,该接口有以下几个方法:

EnterpriseContext get() throws Exception;

void free(EnterpriseContext ctx);

void discard(EnterpriseContext ctx);

int getCurrentSize();

public int getMaxSize();

--------------------------------------------------------------------

先对EnterpriseContext作番说明。EnterpriseContext的作用

就是把具体的EJB instance和它的metadata联系起来。

该类签名为:

public abstract class EnterpriseContext,

有4个子类,EntityEnterpriseContext,MessageDrivenEnterpriseContext,

StatefulSessionEnterpriseContext,StatelessSessionEnterpriseContext。

分别对应4种类型的EJB。

EnterpriseContext中有几个重要的成员变量。

/** The EJB instance */

Object instance;

/** The container using this context */

Container con; //Container这个类是JBoss用来代表对EJB提供Transaction,Security,Pool等服务的类,我们回头还会再说。

/** Only StatelessSession beans have no Id, stateful and entity do */

Object id;

/** The transaction associated with the instance */

Transaction transaction; //Transaction,我们下节再说.

// Constructors --------------------------------------------------

public EnterpriseContext(Object instance, Container con)

{

this.instance = instance;

this.con = con;

}

public Object getInstance()

{

return instance;

}

public Container getContainer() {

return con;

}

public void setId(Object id) {

this.id = id;

}

public Object getId() {

return id;

}

public void setTransaction(Transaction transaction) {

this.transaction = transaction;

}

public Transaction getTransaction() {

return transaction;

}

/**

* Get the EJBContext object

*/

public abstract EJBContext getEJBContext(); //由子类实现

//返回javax.ejb.EJBContext,注意这个EJBContext是

EJB规范要求提供给EJB的Context,与JBoss自己实现类EnterpriseContext没有关系。

/** The instance is being used. This locks it\'s state */

int locked = 0;

public void lock()

{

locked ++;

}

public void unlock() {

locked --;

}

public boolean isLocked() {

return locked != 0;

}

//lock这个成员变量表示当前这个EJB instance有没人在用。

//这个变量用来给Reentrance,以及canPassviate用.

/**

* before reusing this context we clear it of previous state called

* by pool.free()

* 从pool里取出来的时候没有关联任何EJB instance和Transaction信息

* 在返还pool的时候把这些信息清掉。

*/

public void clear() {

this.id = null;

this.locked = 0;

this.transaction = null;

}

//-------------------------------------------------------------------------------------

protected boolean isContainerManagedTx()

{

BeanMetaData md = (BeanMetaData)con.getBeanMetaData();

return md.isContainerManagedTx();

}

//从关联的container拿出对应的metadata,判断是否CMT.

//注意这里con是Container成员变量,可不是什么连接,连接一般缩写为conn,

//我一开始就搞混了:)

//BeanMetaData这些MetaData的子类都是从xml配置里头读出来的Metadata构造的,

//没什么神秘的.

这个类里头还有两个inner class,EJBContextImpl implements EJBContext,

UserTransactionImpl implements UserTransaction。EJBContextImpl等

讲解过Container再说,UserTransaction等下节再说。

现在让我们来看看EnterpriseContext的几个子类:

首先类比一下几个子类的成员变量:

EntityEnterpriseContext:

private EJBObject ejbObject;

private EJBLocalObject ejbLocalObject;

private EntityContext ctx;

StatefulSessionEnterpriseContext

private EJBObject ejbObject;

private EJBLocalObject ejbLocalObject;

private SessionContext ctx;

StatelessSessionEnterpriseContext

EJBObject ejbObject;

EJBLocalObject ejbLocalObject;

SessionContext ctx;

MessageDrivenEnterpriseContext:

private MessageDrivenContext ctx;

看来除了MDB没有对应的EJBObject/EJBLocalObject,其他统统都有:)

学过EJB的人都知道,在语法上EJB instance 是implements

EntityBean/SessionBean/MessageDrivenBean (这3个interface有一个共同的

interface: public interface EnterpriseBean extends Serializable,

EnterpriseBean 是个Marker接口,里头什么都没有,好像Serializable接口一样,只说明

实现它的是个EJB.而EntityBean/SessionBean/MessageDrivenBean 有对应的

void ejbActivate() throws EJBException, RemoteException;

void ejbLoad() throws EJBException, RemoteException;

一些方法需要实现。(虽然常常是空实现:),由容器作了很多事)

至于EJBObject/EJBLocalObject 在语法上都是非直接实现的,代表EJB instance暴露出的Remote/Local 接口。既然这些EJB instance非直接实现这些接口,那么这些接口如何与具体的EJB instance相关联,我们讲到Container类时就知道了。

----------------------------------------------------------------------------------

EnterpriseContext的子类EntityEnterpriseContext的构造函数

public EntityEnterpriseContext(Object instance, Container con)

throws RemoteException

{

super(instance, con);

ctx = new EntityContextImpl(); //这是EJBContextImpl的子类,不急着说:)

((EntityBean)instance).setEntityContext(ctx);//看看,原来set...Context是在这里调用的//其它instance实现的什么ejbCreate(),EJBLoad,EJBActive()到底是什么时候

调用的呢?接下来我们慢慢找,这可散布在各地呢:)

}

//其他几个子类的构造函数前3行也都如此,是类似的。

对于StatelessSessionEnterpriseContext和MessageDrivenEnterpriseContext,紧接的是

Method ejbCreate = instance.getClass().getMethod(\"ejbCreate\", new Class[0]);

ejbCreate.invoke(instance, new Object[0]);

//看看,来了一个ejbCreate:),对于StatelessSessionBean,一上来就ejbCreate()了~

接下来看点简单的:对于EnterpriseContext,

有public abstract void discard() throws RemoteException;

对于MessageDriven...的

public void discard() throws RemoteException

{

((MessageDrivenBean)instance).ejbRemove();

}

对于StatelessSession的

public void discard() throws RemoteException

{

((SessionBean)instance).ejbRemove();

}

对于StatefulSession...的

public void discard() throws RemoteException

{

// Do nothing

}

对于Entity....

public void discard() throws RemoteException

{

((EntityBean)instance).unsetEntityContext();

}

//discard 是在AbstractInstancePool中的

void discard(EnterpriseContext ctx);调用的

/**

* Discard an anonymous instance after invocation.

* This is called if the instance should not be reused, perhaps due to some

* exception being thrown from it.

*

* @param ctx The context to discard.

*/

public void discard(EnterpriseContext ctx)

{

ctx.discard();

}

AbstractInstancePool还有个free方法:

public void free(EnterpriseContext ctx) {

ctx.clear();//记得ctx只是清掉id,transaction等,返回pool,准备复用么?

//discard是在发生错误的时候,不希望扩大影响,于是discard掉,

//而对应get()的free方法只是把EnterpriseContext返还给pool.

}

----------------------------------------------------------------------------------

专门对于Stateful....Context有设置EJB instance的函数

/**

* During activation of stateful session beans we replace the instance

* by the one read from the file.

*/

public void setInstance(Object instance)

{

this.instance = instance;

((SessionBean)instance).setSessionContext(ctx);

}

注意在4种...Context中,只有Stateful...Context签名

public class StatefulSessionEnterpriseContext

extends EnterpriseContext

implements Serializable

多了个implements Serializable,(其他都没有),

这是为了支持Activation/Passviation,Passviation的时候

把EJB Instance写到文件中。

在StatefulSessionEnterpriseContext中有这样两个方法

private void writeObject(ObjectOutputStream out)

throws IOException, ClassNotFoundException

{

// do nothing

}

private void readObject(ObjectInputStream in)

throws IOException, ClassNotFoundException

{

// do nothing

}

//说明序列化的时候StatefulSessionEnterpriseContext本身不需要

写出什么状态,只有对应的EJB instance才需要写出状态。

现在来看AbstractInstancePool的源码,由于内容太多

就不详细解释了。

先看Abstract...Pool的create(Object instance)函数热热身~

Abstract...Pool

// Protected -----------------------------------------------------

protected abstract EnterpriseContext create(Object instance)

throws Exception;

对Entity...Pool

protected EnterpriseContext create(Object instance)

throws Exception

{

return new EntityEnterpriseContext(instance, getContainer());

}

其他3种Pool类似。

再回头看Abstract..Pool

/** The pool data structure */

protected EnterpriseContext[] pool;

protected int currentIndex = -1;

/** The maximum number of instances allowed in the pool */

protected int maxSize = 30;

/** The minimum size of the pool */

protected int minSize = 0;

/** determine if we reuse EnterpriseContext objects i.e. if we actually do pooling */

protected boolean reclaim = false;//对于MDB和StatelessSessionBean,这个变量被设为true,// for MDB, we *do* pool // for SLSB, we *do* pool

ok,现在来看pool的重头戏,get()/free(EnterpriseContext ctx)函数

(discard(EnterpriseContext ctx)前面讲过,不再重复)

这几个函数也是Interface InstancePool里头要实现的接口:)

闲话少说,来看代码~~

protected boolean minSizeInitialized = false;

/**

* Get an instance without identity.

* Can be used by finders,create-methods, and activation

*

* @return Context /w instance

* @exception RemoteException

*/

public EnterpriseContext get() {

//pool里头有东东就拿出来

synchronized (pool)

{

if (currentIndex > -1)

{

EnterpriseContext ctx = pool[currentIndex];

pool[currentIndex--] = null;

return ctx;

}

}

//initialize a small fixed size of instance at startup.

if (!minSizeInitialized)

{

minSizeInitialized = true;

synchronized (pool)

{

for (int i = 0; i < minSize; i++)

{

pool[++currentIndex] = create(container.createBeanClassInstance());

}

}

}

// Pool is empty, create an instance

return create(container.createBeanClassInstance());

}

/**

* Return an instance after invocation.

*

* Called in 2 cases:

* a) Done with finder method

* b) Just removed

*

* @param ctx

*/

public void free(EnterpriseContext ctx) {

ctx.clear();

synchronized (pool)

{

if (currentIndex + 1 < maxSize)

{

pool[++currentIndex] = ctx;

}

}

}

对于Entity...Pool,他overwrite了free

/**

* Return an instance to the free pool. Reset state

*

*

Called in 3 cases:

*

*

Done with finder method

*

Removed

*

Passivated

*

*

* @param ctx

*/

public void free(EnterpriseContext ctx)

{

// If transaction still present don\\\\\\\\\\\\\\\'t do anything (let the instance be GC)

if (ctx.getTransaction() != null)

{

return ;

}

super.free(ctx);

}

-----------------------------------------------------

而Stateful....Pool的free方法overwrite了Abstract...Pool的,

public synchronized void free(EnterpriseContext ctx)

{

discard(ctx);//干脆就discard掉不用了~

}

剩下的下回再讲,先预告2个类体系:

1.AbstractInstanceCache ,有EntityInstanceCache和StatefulSessionInstanceCache 子类。对于Entity,用它的

PrimaryKey作Cache的Key,对于Stateful,Jboss也会付给

每个instance一个唯一标定的值用来做CacheKey.

Abstract...Cache与Abstract...Pool结合使用,得到好的Performance。

2.public abstract class Container,

有EntityContainer,MessageDrivenContainer,Stateful/StatelessSessionContainer

4个子类,用来提供对EJB instance的transaction/security/pool等服务。

//看看它的成员变量,就能猜个大概

/** This is the TransactionManager */

protected TransactionManager tm;

/** This is the SecurityManager */

protected AuthenticationManager sm;

/** This is the instancepool that is to be used */

protected InstancePool instancePool;

开始讲Container,以前说过Container有4种子类,分别对应4种类型的EJB.

一个Container是所有Container plugins(注1)和metadata(注2)的集散地,the container plugins可以从container拿到metadata和其他container plugins.EJB部署的时候会创建相应的Container.Container基本不做太多事,主要delegate给plugins作事情。

ok,让我们来看看Container的成员变量:

/**

* This is the new metadata. it includes information from both ejb-jar and

* jboss.xml the metadata for the application can be accessed trough

* metaData.getApplicationMetaData()

*/

protected BeanMetaData metaData;

/** This is the EnterpriseBean class */

protected Class beanClass;

/** This is the Home interface class */

protected Class homeInterface;

/** This is the Remote interface class */

protected Class remoteInterface;

/** The local home interface class */

protected Class localHomeInterface;

/** The local inteface class */

protected Class localInterface;

/** This is the TransactionManager */

protected TransactionManager tm;

/** This is the SecurityManager */

protected AuthenticationManager sm;

/** This is the realm mapping */

protected RealmMapping rm;

/** This is the bean lock manager that is to be used */

protected BeanLockManager lockManager;

/** This is the application that this container is a part of */

protected EjbModule ejbModule;

//ejbModule作为一个单元部署的Module,比如一个ejb-jar就是一个Module,

/*这个 ejb-jar里头可能有多个entitybean,sessionbean,那么对于 每个entitybean,sessionbean

都会有一个对应的container,而这些东东共享一个ejbModule.*/

/**

* Returns a new instance of the bean class or a subclass of the bean class.

* This factory style method is speciffically used by a container to supply

* an implementation of the abstract accessors in EJB2.0, but could be

* usefull in other situations. This method should ALWAYS be used instead

* of getBeanClass().newInstance();

*

* @return the new instance

*

* @see java.lang.Class#newInstance

*/

public Object createBeanClassInstance() throws Exception {

return getBeanClass().newInstance();

}

public Class getBeanClass()

{

return beanClass;

}

注意EntityContainer overwrite了这个方法:

/**

* Returns a new instance of the bean class or a subclass of the bean class.

* If this is 1.x cmp, simply return a new instance of the bean class.

* If this is 2.x cmp, return a subclass that provides an implementation

* of the abstract accessors.

*

* @see java.lang.Class#newInstance

*

* @return The new instance.

*/

public Object createBeanClassInstance() throws Exception {

return persistenceManager.createBeanClassInstance();

}

其中 persistenceManager声明为:

/** This is the persistence manager for this container */

protected EntityPersistenceManager persistenceManager;

//persitenceManager和PersistenceStore我们将在第3部分讲解。

现在先给个大略印象:

BMPPersistenceManager实现

public Object createBeanClassInstance() throws Exception {

return con.getBeanClass().newInstance();

}

CMPPersistenceManager实现

EntityPersistenceStore store;

public Object createBeanClassInstance() throws Exception

{

return store.createBeanClassInstance();

}

-------------------------------------------------------------------

ok,接下来看看Container如何处理Client过来的Invocation。

一切精彩尽在下面这个函数

public Object invoke(Invocation mi);

//Invocation代表了Client端过来的调用

//Invocation里头有些成员变量,指明了要调用的Method,

//args,Transaction信息,principle/credential等信息。

/** Maps for MarshalledInvocation mapping */

protected Map marshalledInvocationMapping = new HashMap();

public Object invoke(Invocation mi)

throws Exception

{

Thread currentThread = Thread.currentThread();

ClassLoader callerClassLoader = currentThread.getContextClassLoader();

//保存原来的classloader,在finally里恢复

Method m = null;

Object type = null;

try

{

currentThread.setContextClassLoader(this.classLoader);(注3)

// Check against home, remote, localHome, local, getHome,

// getRemote, getLocalHome, getLocal

type = mi.getType();

if(type == InvocationType.REMOTE ||

type == InvocationType.LOCAL)

{

if (mi instanceof MarshalledInvocation)

{

((MarshalledInvocation) mi).setMethodMap(

marshalledInvocationMapping);

}

return internalInvoke(mi);

}

else if(type == InvocationType.HOME ||

type == InvocationType.LOCALHOME)

{

if (mi instanceof MarshalledInvocation)

{

((MarshalledInvocation) mi).setMethodMap(

marshalledInvocationMapping);

return internalInvokeHome(mi);

}

else

{

throw new MBeanException(new IllegalArgumentException(

\\\\\\\"Unknown invocation type: \\\\\\\" + type));

}

}

finally

{

currentThread.setContextClassLoader(callerClassLoader);

}

}

----------------------------------------------------------------

MarshalledInvocation是Invocation的字类,代表可以从

Client传到Server的Invocation

public class Invocation...

public class MarshalledInvocation

extends Invocation

implements java.io.Externalizable

而Invocation是在server端的调用链(Interceptor链,注4)

间传递.

-------------------------------------------------------

ok,稍喘口气,接下来看看两个Internal的invoke,

都是abstract,在字类实现

public abstract Object internalInvokeHome(Invocation mi)

throws Exception;

public abstract Object internalInvoke(Invocation mi)

throws Exception;

至于具体实现么,TO BE CONITUE拉:)

----------------------------------------------------

注1:ContainerPlugin可以放在容器里头的东东。

接口为interface ContainerPlugin :

void setContainer(Container con);

有InstancePool,InstanceCache,EJBProxyFactory/LocalProxyFactory,

EntityPersistenceManager/EntityPersistenceStore等Plugin

注2:metadata描述部署的信息,比如ejb-jar.xml,描述什么东东是

entitybean,什么东东是sessionbean,session的是BMP/CMP等等。

注3: Container的成员变量protected ClassLoader classLoader;

用来load 这个Container里头的类和资源,之所以要专门设一个Container

的classLoader是因为能使EJB re-deployable.(JBoss定期扫描deploy目录,

如果ejb更改就进行redeploy,如果ejb删除就undeploy)

注4: Jboss会建立一个Interceptor 链,Invocation经过链传递。

比如有EntityInterceptor,SecurityInterceptor,TransactionInterceptor,

InvokerInterceptor,一个套一个,每个Interceptor对当前Invocation进行一些处理

,比如检查权限,事物等等,然后传给下一个Interceptor处理(这是Filter and Pipe模式了,也算是AOP拉~,别人说

JBoss 这个Interceptor实现属于AOP方言特别重:)。

所有的Interceptor都是现

Object invokeHome(Invocation mi) throws Exception;

和Object invoke(Invocation mi) throws Exception;

在自己invoke的最后,

经过所有的Interceptor之后,调用下一个。

看看AbstractInterceptor的缺省实现:

public abstract class AbstractInterceptor

implements Interceptor

public Object invokeHome(final Invocation mi) throws Exception {

//do sth.

return getNext().invokeHome(mi);

}

public Object invoke(final Invocation mi) throws Exception {

//do sth.

return getNext().invoke(mi);

}

在经过重重Interceptor之后

最后到达EJB Instance 调用你要的那个方法。

其实实现很简单:

public Object internalInvokeHome(Invocation mi) throws Exception

{

return getInterceptor().invokeHome(mi);

}

public Object internalInvoke(Invocation mi) throws Exception

{

// Invoke through interceptors

return getInterceptor().invoke(mi);

}

public Interceptor getInterceptor()

{

return interceptor;

}

protected Interceptor interceptor;

//这是Container建立的Interceptor链的头一个,从这里调起~

再来看看 void addInterceptor(Interceptor in);这个函数

在Interceptor链最后再挂一个Interceptor

public void addInterceptor(Interceptor in)

{

if (interceptor == null)

{

interceptor = in;

}

else

{

Interceptor current = interceptor;

while (current.getNext() != null)

{

current = current.getNext();

}

current.setNext(in);

}

}

------------------------------------------------------------------------

附带再提一下pool和cache

/** This is the instance cache for this container */

protected InstanceCache instanceCache;

/** This is the instancepool that is to be used */

protected InstancePool instancePool;

/** This is the instancepool that is to be used */

protected InstancePool instancePool;

-------------------------------------------------------------

public void setInstanceCache(InstanceCache ic)

{

if (ic == null)

throw new IllegalArgumentException(\\\"Null cache\\\");

this.instanceCache = ic;

ic.setContainer(this);

}

public InstanceCache getInstanceCache()

{

return instanceCache;

}

public void setInstancePool(InstancePool ip)

{

if (ip == null)

throw new IllegalArgumentException(\\\"Null pool\\\");

this.instancePool = ip;

ip.setContainer(this);

}

-----------------------------------------------------------------------

ok,现在让我们来看看Container都对EJB Instance暴露出来的

方法都作了些什么,还有如何调用EJB Instance的方法.

这里有重要的2个Map

/**

* These are the mappings between the home interface methods and the

* container methods.

* 所有Home 方法映射都存这里

*/

protected Map homeMapping = new HashMap();

/**

* These are the mappings between the remote/local interface methods and the

* bean methods.

* 所有EJBObject方法映射都存这里

*/

protected Map beanMapping = new HashMap();

--------------------------------------------------------------------------

class ContainerInterceptor

extends AbstractContainerInterceptor

//AbstractContainerInterceptor基本上什么都不做,不用看

//ContainerInterceptor代表Container setup的Interceptor调用

//链的最后一个,到这里你就会看到他调用了你的EJB Instance的方法

{

public Object invokeHome(Invocation mi) throws Exception

{

// Invoke and handle exceptions

Method miMethod = mi.getMethod();

Method m = (Method) homeMapping.get(miMethod);

if (m.getDeclaringClass().equals(EntityContainer.class))

{

try

{

return m.invoke(EntityContainer.this, new Object[] { mi });

}

catch (Exception e)

{

rethrow(e);

}

}

else // Home method

{

try

{

return m.invoke(((EnterpriseContext) mi.getEnterpriseContext()).getInstance(), mi.getArguments());

}

catch (Exception e)

{

rethrow(e);

}

}

// We will never get this far, but the compiler does not know that

throw new org.jboss.util.UnreachableStatementException();

}

public Object invoke(Invocation mi) throws Exception

{

// Get method

Method miMethod = mi.getMethod();

Method m = (Method) beanMapping.get(miMethod);

if( m == null )

{

String msg = \\\"Invalid invocation, check your deployment packaging\\\"

+\\\", method=\\\"+miMethod;

throw new EJBException(msg);

}

// Select instance to invoke (container or bean)

if (m.getDeclaringClass().equals(EntityContainer.class))

{

// Invoke and handle exceptions

try

{

return m.invoke(EntityContainer.this, new Object[]{ mi });

}

catch (Exception e)

{

rethrow(e);

}

}

else

{

// Invoke and handle exceptions

try

{

return m.invoke(((EnterpriseContext) mi.getEnterpriseContext()).getInstance(), mi.getArguments());

}

catch (Exception e)

{

rethrow(e);

}

}

// We will never get this far, but the compiler does not know that

throw new org.jboss.util.UnreachableStatementException();

}

}

//可以看到,两个Map作了个映射,Map的Key为

在你想要调用的EJB instance方法,value为实际

实现的方法,可能就是EJB instance本身实现的方法,

或者是容器帮忙实现的(比如CMP 中abstract get/set方法,

只能容器帮忙实现).

从这里也可以看出来,JBoss主要是保存了方法映射来处理

EJBObject/EJBLocalObject 的调用请求,

而其他一些J2EE AS是通过动态生成EJBObject/EJBLocalObject

和你的EJB Instance的字类来实现的(而JBoss就算在CMP2.0

里动态生成了一个东东,那也不是EJB Instance的子类)。

ok,基本弄明白了Container的原理之后,我们来看看

到底Container的一些初始化操作

Container算是一项服务,

JBoss在deploy/undeploy/redeploy时会调用

与Service相关的几个函数:

protected void createService() throws Exception {}

protected void startService() throws Exception {}

protected void stopService() throws Exception {}

protected void destroyService() throws Exception {}

让我们从EntityContainer看起:

protected void createService() throws Exception

{

// Associate thread with classloader

ClassLoader oldCl = Thread.currentThread().getContextClassLoader();

Thread.currentThread().setContextClassLoader(getClassLoader());

try

{

// Acquire classes from CL

//从metadata拿到Home/Remote的Class

if (metaData.getHome() != null)

homeInterface = classLoader.loadClass(metaData.getHome());

if (metaData.getRemote() != null)

remoteInterface = classLoader.loadClass(metaData.getRemote());

// Call default init

// 调用Container里头的CreateService,我们回头再看

super.createService();

//建立刚才所说的两个Method映射Map

setupBeanMapping();

setupHomeMapping();

// Map the interfaces to Long

setupMarshalledInvocationMapping();

// Initialize pool

instancePool.create();

// Try to register the instance pool as an MBean

try

{

ObjectName containerName = super.getJmxName();

Hashtable props = containerName.getKeyPropertyList();

props.put(\\\"plugin\\\", \\\"pool\\\");

ObjectName poolName = new ObjectName(containerName.getDomain(), props);

server.registerMBean(instancePool, poolName);

}

catch(Throwable t)

{

log.debug(\\\"Failed to register cache as mbean\\\", t);

}

// Init instance cache

instanceCache.create();

// Try to register the instance cache as an MBean

try

{

ObjectName containerName = super.getJmxName();

Hashtable props = containerName.getKeyPropertyList();

props.put(\\\"plugin\\\", \\\"cache\\\");

ObjectName cacheName = new ObjectName(containerName.getDomain(), props);

server.registerMBean(instanceCache, cacheName);

}

catch(Throwable t)

{

log.debug(\\\"Failed to register cache as mbean\\\", t);

}

for (Iterator it = proxyFactories.keySet().iterator(); it.hasNext(); )

{

String invokerBinding = (String)it.next();

EJBProxyFactory ci = (EJBProxyFactory)proxyFactories.get(invokerBinding);

ci.create();

}

// Init persistence

persistenceManager.create();

// Initialize the interceptor by calling the chain

Interceptor in = interceptor;

while (in != null)

{

in.setContainer(this);

in.create();

in = in.getNext();

}

readOnly = ((EntityMetaData)metaData).isReadOnly();

}

finally

{

// Reset classloader

Thread.currentThread().setContextClassLoader(oldCl);

}

}

protected void startService() throws Exception

{

// Associate thread with classloader

ClassLoader oldCl = Thread.currentThread().getContextClassLoader();

Thread.currentThread().setContextClassLoader(getClassLoader());

try

{

// Call default start

super.startService();

// Start container invokers

for (Iterator it = proxyFactories.keySet().iterator(); it.hasNext(); )

{

String invokerBinding = (String)it.next();

EJBProxyFactory ci = (EJBProxyFactory)proxyFactories.get(invokerBinding);

ci.start();

}

// Start instance cache

instanceCache.start();

// Start persistence

persistenceManager.start();

// Start the instance pool

instancePool.start();

// Start all interceptors in the chain

Interceptor in = interceptor;

while (in != null)

{

in.start();

in = in.getNext();

}

}

finally

{

// Reset classloader

Thread.currentThread().setContextClassLoader(oldCl);

}

}

protected void stopService() throws Exception

{

// Associate thread with classloader

ClassLoader oldCl = Thread.currentThread().getContextClassLoader();

Thread.currentThread().setContextClassLoader(getClassLoader());

try

{

//Stop items in reverse order from start

//This assures that CachedConnectionInterceptor will get removed

//from in between this and the pm before the pm is stopped.

// Stop all interceptors in the chain

Interceptor in = interceptor;

while (in != null)

{

in.stop();

in = in.getNext();

}

// Stop the instance pool

instancePool.stop();

// Stop persistence

persistenceManager.stop();

// Stop instance cache

instanceCache.stop();

// Stop container invoker

for (Iterator it = proxyFactories.keySet().iterator(); it.hasNext(); )

{

String invokerBinding = (String)it.next();

EJBProxyFactory ci = (EJBProxyFactory)proxyFactories.get(invokerBinding);

ci.stop();

}

// Call default stop

super.stopService();

}

finally

{

// Reset classloader

Thread.currentThread().setContextClassLoader(oldCl);

}

}

protected void destroyService() throws Exception

{

// Associate thread with classloader

ClassLoader oldCl = Thread.currentThread().getContextClassLoader();

Thread.currentThread().setContextClassLoader(getClassLoader());

try

{

// Destroy container invoker

for (Iterator it = proxyFactories.keySet().iterator(); it.hasNext(); )

{

String invokerBinding = (String)it.next();

EJBProxyFactory ci = (EJBProxyFactory)proxyFactories.get(invokerBinding);

ci.destroy();

}

// Destroy instance cache

instanceCache.destroy();

instanceCache.setContainer(null);

try

{

ObjectName containerName = super.getJmxName();

Hashtable props = containerName.getKeyPropertyList();

props.put(\\\"plugin\\\", \\\"cache\\\");

ObjectName cacheName = new ObjectName(containerName.getDomain(), props);

server.unregisterMBean(cacheName);

}

catch(Throwable ignore)

{

}

// Destroy persistence

persistenceManager.destroy();

persistenceManager.setContainer(null);

// Destroy the pool

instancePool.destroy();

instancePool.setContainer(null);

try

{

ObjectName containerName = super.getJmxName();

Hashtable props = containerName.getKeyPropertyList();

props.put(\\\"plugin\\\", \\\"pool\\\");

ObjectName poolName = new ObjectName(containerName.getDomain(), props);

server.unregisterMBean(poolName);

}

catch(Throwable ignore)

{

}

// Destroy all the interceptors in the chain

Interceptor in = interceptor;

while (in != null)

{

in.destroy();

in.setContainer(null);

in = in.getNext();

}

MarshalledInvocation.removeHashes(homeInterface);

MarshalledInvocation.removeHashes(remoteInterface);

// Call default destroy

super.destroyService();

}

finally

{

// Reset classloader

Thread.currentThread().setContextClassLoader(oldCl);

}

}

------------------------------------------------------------

protected void setupBeanMapping() throws Exception

{

try {

if (remoteInterface != null)

{

Method[] m = remoteInterface.getMethods();

setupBeanMappingImpl( m, \\\"javax.ejb.EJBObject\\\" );

}

if (localInterface != null)

{

Method[] m = localInterface.getMethods();

setupBeanMappingImpl( m, \\\"javax.ejb.EJBLocalObject\\\" );

}

}

catch (Exception e)

{

// ditch the half built mappings

homeMapping.clear();

beanMapping.clear();

throw e;

}

}

private void setupBeanMappingImpl( Method[] m, String intfName )

throws Exception

{

for (int i = 0; i < m.length; i++)

{

if (!m.getDeclaringClass().getName().equals(intfName))

{

// Implemented by bean

beanMapping.put(m, beanClass.getMethod(m.getName(), m.getParameterTypes()));

}

else

{

// Implemented by container

beanMapping.put(m, getClass().getMethod(m.getName(),

new Class[] { Invocation.class }));

}

}

}

private void setupHomeMappingImpl(Method[] m,

String finderName,

String append)

throws Exception

{

// Adrian Brock: This should go away when we don\\\'t support EJB1x

boolean isEJB1x = metaData.getApplicationMetaData().isEJB1x();

for (int i = 0; i < m.length; i++)

{

String methodName = m.getName();

try

{

try // Try home method

{

String ejbHomeMethodName = \\\"ejbHome\\\" + methodName.substring(0,1).toUpperCase() + methodName.substring(1);

homeMapping.put(m, beanClass.getMethod(ejbHomeMethodName, m.getParameterTypes()));

continue;

}

catch (NoSuchMethodException ignore) {} // just go on with other types of methods

// Implemented by container (in both cases)

if (methodName.startsWith(\\\"find\\\"))

{

homeMapping.put(m, this.getClass().getMethod(finderName, new Class[] { Invocation.class }));

}

else if (methodName.equals(\\\"create\\\") ||

(isEJB1x == false && methodName.startsWith(\\\"create\\\")))

{

homeMapping.put(m, this.getClass().getMethod(\\\"create\\\"+append, new Class[] { Invocation.class }));

beanMapping.put(m, this.getClass().getMethod(\\\"postCreate\\\"+append, new Class[] { Invocation.class }));

}

else

{

homeMapping.put(m, this.getClass().getMethod(methodName+append, new Class[] { Invocation.class }));

}

}

catch (NoSuchMethodException e)

{

throw new NoSuchMethodException(\\\"Could not find matching method for \\\"+m);

}

}

}

protected void setupHomeMapping() throws Exception

{

try {

if (homeInterface != null)

{

Method[] m = homeInterface.getMethods();

setupHomeMappingImpl( m, \\\"find\\\", \\\"Home\\\" );

}

if (localHomeInterface != null)

{

Method[] m = localHomeInterface.getMethods();

setupHomeMappingImpl( m, \\\"findLocal\\\", \\\"LocalHome\\\" );

}

// Special methods

// Get the One on Handle (getEJBObject), get the class

Class handleClass = Class.forName(\\\"javax.ejb.Handle\\\");

// Get the methods (there is only one)

Method[] handleMethods = handleClass.getMethods();

//Just to make sure let\\\'s iterate

for (int j=0; j

{

//Get only the one called handle.getEJBObject

if (handleMethods[j].getName().equals(\\\"getEJBObject\\\"))

{

//Map it in the home stuff

homeMapping.put(handleMethods[j],

this.getClass().getMethod(\\\"getEJBObject\\\",

new Class[] {Invocation.class}));

}

}

}

catch (Exception e)

{

// ditch the half built mappings

homeMapping.clear();

beanMapping.clear();

throw e;

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有