org.apache.myfaces.orchestra.conversation
Class TestScope

java.lang.Object
  extended by junit.framework.Assert
      extended by junit.framework.TestCase
          extended by org.springframework.test.ConditionalTestCase
              extended by org.springframework.test.AbstractSpringContextTests
                  extended by org.springframework.test.AbstractSingleSpringContextTests
                      extended by org.springframework.test.AbstractDependencyInjectionSpringContextTests
                          extended by org.apache.myfaces.orchestra.conversation.TestScope
All Implemented Interfaces:
junit.framework.Test

public class TestScope
extends org.springframework.test.AbstractDependencyInjectionSpringContextTests

Test various aspects of the conversation handling, particularly as they interact with Spring's AOP proxying of various forms.

Spring can generate aop proxies in two ways: with CGLIB and java.lang.reflect.Proxy.

The CGLIB implementation can proxy concrete classes, by creating a new class instance that subclasses the original (but whose methods all simply forward to the attached advices, which then forward to the real target object). These CGLIB proxy classes are not final, ie they can themselves be proxied if necessary (though that is inefficient).

The java.lang implementation can only proxy interfaces; it creates a concrete final class that implements those interfaces, where the method implementations again forward to the attached handlers that then forward to a real target object. Because these generated classes are final, they cannot be subclassed.

Spring doesn't really care about proxies; what it cares about is being able to attach a set of Advice objects to a bean. But in practice, if Advices are to be attached, then there must be a proxy object to attach them to (unless load-time-weaving is supported). Note that "introductory advices" can also be defined, which dynamically add interfaces to the target bean.

Of course Spring doesn't hard-wire advices to beans. Instead when a bean instance is created, the set of registered BeanPostProcessors are run. Some of those may then choose to attach advices; for example Spring's declarative transaction-handling support uses a proxy. Any post-processor that wants to create a proxy should really subclass AbstractAutoProxyCreator. This class handles caching of proxy classes for beans. It also handles the case where multiple BeanPostProcessors want to proxy the same bean, by merging the advices together so that one single proxy instance is needed.

The BeanNameAutoProxyCreator is an interesting BeanPostProcessor that triggers when creating beans with specific names; it simply looks for all registered beans of type Advisor, asks each whether they want to apply to a particular bean, and if so then asks it for an Advice instance to use. Of course the presence of an Advice then causes the ancestor AbstractAutoProxyCreator to create a proxy for the target bean.

When a proxy is created, there is some complex logic to determine whether the jdk or cglib library is used. If the target bean has no interfaces, then cglib is of course used. If the bean has been explicitly marked as "use cglib" then cglib is used. Otherwise java.lang.reflect.Proxy is used.

Orchestra needs to attach its own advices to orchestra beans, in order to implement its persistence support.

There is a standard "scoped proxying" feature that can be applied to a bean by adding aop:scoped-proxy as an element inside a bean definition. This is somewhat different from the above. This proxy always subclasses the real original class of the bean (ie does not include any interfaces added via "introductory advices"). However as a side-effect, the presence of this tag deliberately forces the target bean to be created with CGLIB (not sure why this is done). A "real" bean can therefore effectively have two proxies: a "scoping" one, and an "advising" one. Orchestra generally recommends that aop:scoped-proxy be avoided, and instead implements its own equivalent. However when an aop:scoped-proxy *is* defined for an orchestra-scoped bean, then it detects this and skips the creation of its own equivalent proxy object.

This test case tries to test that Orchestra works correctly when in the presence of all these various proxying options.


Field Summary
 
Fields inherited from class org.springframework.test.AbstractDependencyInjectionSpringContextTests
AUTOWIRE_BY_NAME, AUTOWIRE_BY_TYPE, AUTOWIRE_NO
 
Fields inherited from class org.springframework.test.AbstractSingleSpringContextTests
applicationContext
 
Fields inherited from class org.springframework.test.ConditionalTestCase
logger
 
Constructor Summary
TestScope()
           
 
Method Summary
protected  String[] getConfigLocations()
           
protected  void onSetUp()
           
 void testCorrectConversation()
           
 void testFoo()
           
 void testPlainBean()
           
 
Methods inherited from class org.springframework.test.AbstractDependencyInjectionSpringContextTests
getAutowireMode, injectDependencies, isDependencyCheck, isPopulateProtectedVariables, prepareTestInstance, setAutowireMode, setDependencyCheck, setPopulateProtectedVariables
 
Methods inherited from class org.springframework.test.AbstractSingleSpringContextTests
contextKey, createApplicationContext, customizeBeanFactory, getApplicationContext, getConfigPath, getConfigPaths, getLoadCount, loadContext, loadContextLocations, onTearDown, setDirty, setUp, tearDown
 
Methods inherited from class org.springframework.test.AbstractSpringContextTests
addContext, contextKeyString, getContext, hasCachedContext, setDirty
 
Methods inherited from class org.springframework.test.ConditionalTestCase
getDisabledTestCount, isDisabledInThisEnvironment, recordDisabled, runBare
 
Methods inherited from class junit.framework.TestCase
countTestCases, createResult, getName, run, run, runTest, setName, toString
 
Methods inherited from class junit.framework.Assert
assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, fail, fail
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

TestScope

public TestScope()
Method Detail

getConfigLocations

protected String[] getConfigLocations()
Overrides:
getConfigLocations in class org.springframework.test.AbstractSingleSpringContextTests

onSetUp

protected void onSetUp()
                throws Exception
Overrides:
onSetUp in class org.springframework.test.AbstractSingleSpringContextTests
Throws:
Exception

testFoo

public void testFoo()
             throws Exception
Throws:
Exception

testCorrectConversation

public void testCorrectConversation()
                             throws Exception
Throws:
Exception

testPlainBean

public void testPlainBean()
                   throws Exception
Throws:
Exception


Copyright © 2012 The Apache Software Foundation. All Rights Reserved.