KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > ejb > support > AbstractEnterpriseBean


1 /*
2  * Copyright 2002-2007 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.ejb.support;
18
19 import javax.ejb.EnterpriseBean JavaDoc;
20
21 import org.springframework.beans.BeansException;
22 import org.springframework.beans.FatalBeanException;
23 import org.springframework.beans.factory.BeanFactory;
24 import org.springframework.beans.factory.access.BeanFactoryLocator;
25 import org.springframework.beans.factory.access.BeanFactoryReference;
26 import org.springframework.context.access.ContextJndiBeanFactoryLocator;
27 import org.springframework.util.WeakReferenceMonitor;
28
29 /**
30  * Superclass for all EJBs. Package-visible: not intended for direct subclassing. Provides
31  * a standard way of loading a BeanFactory. Subclasses act as a facade, with the business
32  * logic deferred to beans in the BeanFactory.
33  *
34  * <p>Default is to use a ContextJndiBeanFactoryLocator, which will initialize an XML
35  * ApplicationContext from the class path (based on a JNDI name specified). For a
36  * different locator strategy, <code>setBeanFactoryLocator</code> may be called
37  * (<i>before</i> your EJB's <code>ejbCreate method</code> is invoked, for example,
38  * in <code>setSessionContext</code>). For use of a shared ApplicationContext between
39  * multiple EJBs, where the container class loader setup supports this visibility,
40  * you may instead use a ContextSingletonBeanFactoryLocator. Alternately,
41  * <code>setBeanFactoryLocator</code> may be called with a completely custom
42  * implementation of the BeanFactoryLocator interface.
43  *
44  * <p>Note that we cannot use final for our implementation of EJB lifecycle methods,
45  * as this violates the EJB specification.
46  *
47  * @author Rod Johnson
48  * @author Colin Sampaleanu
49  * @see #setBeanFactoryLocator
50  * @see org.springframework.context.access.ContextJndiBeanFactoryLocator
51  * @see org.springframework.context.access.ContextSingletonBeanFactoryLocator
52  */

53 abstract class AbstractEnterpriseBean implements EnterpriseBean JavaDoc {
54
55     public static final String JavaDoc BEAN_FACTORY_PATH_ENVIRONMENT_KEY = "java:comp/env/ejb/BeanFactoryPath";
56
57
58     /**
59      * Helper strategy that knows how to locate a Spring BeanFactory (or
60      * ApplicationContext).
61      */

62     private BeanFactoryLocator beanFactoryLocator;
63
64     /** factoryKey to be used with BeanFactoryLocator */
65     private String JavaDoc beanFactoryLocatorKey;
66
67     /** Spring BeanFactory that provides the namespace for this EJB */
68     private BeanFactoryReference beanFactoryReference;
69
70
71     /**
72      * Set the BeanFactoryLocator to use for this EJB. Default is a
73      * ContextJndiBeanFactoryLocator.
74      * <p>Can be invoked before loadBeanFactory, for example in constructor or
75      * setSessionContext if you want to override the default locator.
76      * <p>Note that the BeanFactory is automatically loaded by the ejbCreate
77      * implementations of AbstractStatelessSessionBean and
78      * AbstractMessageDriverBean but needs to be explicitly loaded in custom
79      * AbstractStatefulSessionBean ejbCreate methods.
80      * @see AbstractStatelessSessionBean#ejbCreate
81      * @see AbstractMessageDrivenBean#ejbCreate
82      * @see AbstractStatefulSessionBean#loadBeanFactory
83      * @see org.springframework.context.access.ContextJndiBeanFactoryLocator
84      */

85     public void setBeanFactoryLocator(BeanFactoryLocator beanFactoryLocator) {
86         this.beanFactoryLocator = beanFactoryLocator;
87     }
88
89     /**
90      * Set the bean factory locator key.
91      * <p>In case of the default BeanFactoryLocator implementation,
92      * ContextJndiBeanFactoryLocator, this is the JNDI path. The default value
93      * of this property is "java:comp/env/ejb/BeanFactoryPath".
94      * <p>Can be invoked before loadBeanFactory, for example in constructor or
95      * setSessionContext if you want to override the default locator key.
96      * @see #BEAN_FACTORY_PATH_ENVIRONMENT_KEY
97      */

98     public void setBeanFactoryLocatorKey(String JavaDoc factoryKey) {
99         this.beanFactoryLocatorKey = factoryKey;
100     }
101
102     /**
103      * Load a Spring BeanFactory namespace. Subclasses must invoke this method.
104      * <p>Package-visible as it shouldn't be called directly by user-created
105      * subclasses.
106      * @see org.springframework.ejb.support.AbstractStatelessSessionBean#ejbCreate()
107      */

108     void loadBeanFactory() throws BeansException {
109         if (this.beanFactoryLocator == null) {
110             this.beanFactoryLocator = new ContextJndiBeanFactoryLocator();
111         }
112         if (this.beanFactoryLocatorKey == null) {
113             this.beanFactoryLocatorKey = BEAN_FACTORY_PATH_ENVIRONMENT_KEY;
114         }
115
116         this.beanFactoryReference = this.beanFactoryLocator.useBeanFactory(this.beanFactoryLocatorKey);
117
118         // We cannot rely on the container to call ejbRemove() (it's skipped in
119
// the case of system exceptions), so ensure the the bean factory
120
// reference is eventually released.
121
WeakReferenceMonitor.monitor(this, new BeanFactoryReferenceReleaseListener(this.beanFactoryReference));
122     }
123
124     /**
125      * Unload the Spring BeanFactory instance. The default {@link #ejbRemove()}
126      * method invokes this method, but subclasses which override <code>ejbRemove</code>
127      * must invoke this method themselves.
128      * <p>Package-visible as it shouldn't be called directly by user-created
129      * subclasses.
130      */

131     void unloadBeanFactory() throws FatalBeanException {
132         // We will not ever get here if the container skips calling ejbRemove(),
133
// but the WeakReferenceMonitor will still clean up (later) in that case.
134
if (this.beanFactoryReference != null) {
135             this.beanFactoryReference.release();
136             this.beanFactoryReference = null;
137         }
138     }
139
140     /**
141      * May be called after ejbCreate().
142      * @return the bean factory
143      */

144     protected BeanFactory getBeanFactory() {
145         return this.beanFactoryReference.getFactory();
146     }
147
148     /**
149      * EJB lifecycle method, implemented to invoke onEjbRemote and unload the
150      * BeanFactory afterwards.
151      * <p>Don't override it (although it can't be made final): code your shutdown
152      * in onEjbRemove.
153      * @see #onEjbRemove
154      */

155     public void ejbRemove() {
156         onEjbRemove();
157         unloadBeanFactory();
158     }
159
160     /**
161      * Subclasses must implement this method to do any initialization they would
162      * otherwise have done in an ejbRemove() method. The BeanFactory will be
163      * unloaded afterwards.
164      * <p>This implementation is empty, to be overridden in subclasses. The same
165      * restrictions apply to the work of this method as to an ejbRemove() method.
166      */

167     protected void onEjbRemove() {
168         // empty
169
}
170
171
172     /**
173      * Implementation of WeakReferenceMonitor's ReleaseListener callback interface.
174      * Release the given BeanFactoryReference if the monitor detects that there
175      * are no strong references to the handle anymore.
176      */

177     private static class BeanFactoryReferenceReleaseListener implements WeakReferenceMonitor.ReleaseListener {
178
179         private final BeanFactoryReference beanFactoryReference;
180
181         public BeanFactoryReferenceReleaseListener(BeanFactoryReference beanFactoryReference) {
182             this.beanFactoryReference = beanFactoryReference;
183         }
184
185         public void released() {
186             this.beanFactoryReference.release();
187         }
188     }
189
190 }
191
Popular Tags