Announcement Announcement Module
Collapse
No announcement yet.
Using ContextSingletonBeanFactoryLocator with EJBs Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Using ContextSingletonBeanFactoryLocator with EJBs

    I have a given applicationContext.xml that I would like to share across all of my EJBs. Say I have a SLSB of Type1, and another SLSB of Type2. Is there any way to have a "global" ApplicationContext for all SLSB instances of Type1, and a separate "global" AC for all SLSB instances of Type2?

    The main reason for my question is that Type1 and Type2 both do similar operations using the same DAOs with the same datasource references, however, they do them using different isolation levels (one uses TRANSACTION_READ_SERIALIZABLE, while the other uses TRANSACTION_READ_UNCOMMITTED). I assume if Type1 and Type2 share a singleton ApplicationContext, they will stomp over each others transaction isolation levels.

    Perhaps I could define the datasource as non-singleton. What are the ramifications of that?

    The secondary reason for desiring to use a "singleton" AC is because of the number of instances of EJBs per type that get instantiated is quite large.

    I find it undesirable to create a separate applicationContext.xml for each bean (as the content would be identical). Defining aliases wouldn't work, because they refer to the same BeanFactory instance. Is there anything that would do what I need? Subclass ContextSingletonBeanFactoryLocator and override useBeanFactory?--also sounds distasteful.

    Thanks.

  • #2
    In setSessionContext you would set:

    Code:
      setBeanFactoryLocator(ContextSingletonBeanFactoryLocator.getInstance());
      setBeanFactoryLocatorKey("Type1.context");
    So your EJB would use a shared context. If you wanted two shared contexts, you'd need to create two different contexts identified by two different beanFactoryLocatorKey (Type1.context, Type2.context). They could share the same application context files. In fact they could share any XML files they wanted, and could differ however you wanted.

    Since you want to change the isolation levels between the beans you'd need some different XML files as well as shared:

    Type1.xml:
    Code:
    <bean id="sharedTransactionAttributes" class="java.util.Properties>
      <constructor-arg>
        <props>
        <!-- transaction attributes go here -->
        </props>
      </constructor-arg>
    </bean>
    Type2.xml:
    Code:
    <bean id="sharedTransactionAttributes" class="java.util.Properties>
      <constructor-arg>
        <props>
        <!-- transaction attributes go here -->
        </props>
      </constructor-arg>
    </bean>
    SharedComponents.xml
    Code:
    <bean id="blah" class="TransactionProxyFactoryBean">
      <property name="transactionAttributes ref="sharedTransactionAttributes"/>
      <!-- other stuff goes here -->
    </bean>
    beanRefContext.xml:
    Code:
    <bean id="Type1.context" class="org.springframework.context.support.ClassPathXmlApplicationContext">
      <constructor-arg value="Type1.xml,SharedComponents.xml"/>
    </bean>  
    
    <bean id="Type2.context" class="org.springframework.context.support.ClassPathXmlApplicationContext">
      <constructor-arg value="Type2.xml,SharedComponents.xml"/>
    </bean>
    Note that the name of the beans is the name of the beanFactoryLocatorKey.

    Your system will have two copies of the shared components, one tailored to your Type1 scenario and another for the Type2 scenario.

    Although there isn't any reason to use a ContextSingletonBeanFactoryLocator, since that only refers to what kind of class is used to process the beanRefContext.xml. A SingletonBeanFactoryLocator would work just as well. Just change the name of beanRefContext.xml to beanRefFactory.xml. See the javadoc for these two classes to get more information about them.

    Comment


    • #3
      Originally posted by wpoitras
      In setSessionContext you would set:

      Since you want to change the isolation levels between the beans you'd need some different XML files as well as shared:
      Thanks for the info, so basically, I just need to set up a context for each EJB in the beanRef.xml (which each in turn just reference the single applicationContext.xml).

      The difference in my situation is that I retrieve the DataSource from JNDI and use app server extensions to configure the isolation level on the datasource-ref as we cannot configure the isolation level on the JtaTransactionManager. So both EJBs use the same datasource ref (e.g. java:comp/env/jdbc/datasource) yet get different isolation levels depending on which bean they are. That means both EJBs use the exact applicationContext.xml.

      Comment

      Working...
      X