[jboss-cvs] jboss-seam/examples/spring/src/org/jboss/seam/ioc/spring ...
Norman Richards
norman.richards at jboss.com
Fri Feb 16 17:43:24 EST 2007
User: nrichards
Date: 07/02/16 17:43:24
Modified: examples/spring/src/org/jboss/seam/ioc/spring
SeamFactoryBean.java SeamNamespaceHandler.java
SeamScope.java SpringComponent.java spring.xsd
Added: examples/spring/src/org/jboss/seam/ioc/spring
SeamComponentPostProcessor.java
SeamScopePostProcessor.java SeamTargetSource.java
TestAnnotation.java TestInterceptor.java
Removed: examples/spring/src/org/jboss/seam/ioc/spring
SeamPostProcessor.java
Log:
spring updates
Revision Changes Path
1.3 +85 -43 jboss-seam/examples/spring/src/org/jboss/seam/ioc/spring/SeamFactoryBean.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: SeamFactoryBean.java
===================================================================
RCS file: /cvsroot/jboss/jboss-seam/examples/spring/src/org/jboss/seam/ioc/spring/SeamFactoryBean.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- SeamFactoryBean.java 15 Feb 2007 07:34:59 -0000 1.2
+++ SeamFactoryBean.java 16 Feb 2007 22:43:24 -0000 1.3
@@ -1,12 +1,25 @@
package org.jboss.seam.ioc.spring;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpSessionActivationListener;
+
import org.jboss.seam.Component;
+import org.jboss.seam.InterceptionType;
import org.jboss.seam.ScopeType;
+import org.jboss.seam.core.Mutable;
+import org.jboss.seam.intercept.Proxy;
+import org.springframework.aop.framework.DefaultAopProxyFactory;
+import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.AbstractFactoryBean;
/**
- * Provides an instance of a Seam Component in the current context given the name.
+ * Obtains an instance of a Seam Component in the current context
+ * given the name and other optional parameters. If proxy is set to
+ * true then return a scoped proxy of the seam component instance. Use
+ * <seam:instance/> to simplify use of this factory.
*
* @author youngm
*/
@@ -17,89 +30,118 @@
private ScopeType scope;
private String name;
private Boolean create;
-
- public SeamFactoryBean()
- {
- setSingleton(false);
- }
-
+ private SeamTargetSource targetSource;
+ private Object proxyInstance;
+ private boolean proxy = false;
/**
- * Ensure name is not null
+ * Initializes the factory. If proxy=true then initialize the proxy.
*
* @see org.springframework.beans.factory.config.AbstractFactoryBean#afterPropertiesSet()
*/
@Override
- public void afterPropertiesSet()
- throws Exception
- {
+ public void afterPropertiesSet() throws Exception {
if (name == null) {
throw new IllegalArgumentException("name must not be null");
}
+ // If we're creating a proxy then we want this to be a singleton
+ setSingleton(proxy);
+
+ this.targetSource = new SeamTargetSource(name, scope, create);
+
+ if (proxy) {
+ // Not sure if I should allow people to change these proxy
+ // parameters or not. We'll see what issues we get hard coding them.
+ ProxyFactory pf = new ProxyFactory();
+ pf.setProxyTargetClass(true);
+ pf.setOptimize(true);
+ pf.setExposeProxy(false);
+ pf.setFrozen(true);
+ pf.setAopProxyFactory(new DefaultAopProxyFactory());
+ pf.setTargetSource(this.targetSource);
+
+ // Attempt to piece together all of the possible interfaces to apply
+ // to our proxy.
+ List<Class> interfaces = new ArrayList<Class>();
+ Component component = targetSource.getComponent();
+ if (component.getInterceptionType() != InterceptionType.NEVER) {
+ if (component.getType().isSessionBean()) {
+ interfaces.addAll(component.getBusinessInterfaces());
+ } else {
+ interfaces.add(HttpSessionActivationListener.class);
+ interfaces.add(Mutable.class);
+ }
+ interfaces.add(Proxy.class);
+ }
+ pf.setInterfaces(interfaces.toArray(new Class[interfaces.size()]));
+
+ this.proxyInstance = pf.getProxy();
+ }
super.afterPropertiesSet();
}
/**
- * Return the current instance of a Seam component given the current context.
+ * Return the current instance of a Seam component or the proxy if proxy was set to true.
*
* @see org.springframework.beans.factory.config.AbstractFactoryBean#createInstance()
*/
@Override
- protected Object createInstance()
- throws Exception
- {
- if (scope == null && create == null) {
- return Component.getInstance(name);
- } else if (scope == null) {
- return Component.getInstance(name, create);
- } else if (create == null) {
- return Component.getInstance(name, scope);
+ protected Object createInstance() throws Exception {
+ if (proxy) {
+ return proxyInstance;
} else {
- return Component.getInstance(name, scope, create);
+ return targetSource.getTarget();
}
}
-
/**
- * Return the type of the component if it is available.
+ * Return the type of the component if available.
+ *
+ * @throws IllegalStateException if the component cannot be found or if seam has not yet been initialized.
*
* @see org.springframework.beans.factory.config.AbstractFactoryBean#getObjectType()
*/
@Override
- public Class getObjectType()
- {
- Component component = Component.forName(name);
- if (component == null) {
- return null;
- }
- return component.getBeanClass();
+ public Class getObjectType() {
+ return targetSource.getTargetClass();
}
/**
- * The seam component name
+ * The name of the seam component to get an instance of. (required)
*
- * @param name the name to set
+ * @param name the name of the component
*/
- public void setName(String name)
- {
+ public void setName(String name) {
this.name = name;
}
/**
- * The seam component scope (optional)
+ * The scope of the seam component (optional)
*
- * @param scope the scope to set
+ * @param scope the scope of the component
*/
- public void setScope(ScopeType scope)
- {
+ public void setScope(ScopeType scope) {
this.scope = scope;
}
/**
- * Weather to create an instance of the component if one doesn't already exist in this context.
+ * Should the factory create an instance of the component if one
+ * doesn't already exist in this context. If null
+ *
+ * Must always be true for STATELESS components.
*
- * @param create the create to set
+ * @param create do we create an instance if needed
*/
public void setCreate(Boolean create) {
this.create = create;
}
+
+ /**
+ * Should the factory wrap the component instance in a proxy so
+ * the seam component can be safely injected into a singleton.
+ *
+ * @param proxy true to proxy the component
+ */
+ public void setProxy(boolean proxy) {
+ this.proxy = proxy;
+ }
}
1.3 +152 -13 jboss-seam/examples/spring/src/org/jboss/seam/ioc/spring/SeamNamespaceHandler.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: SeamNamespaceHandler.java
===================================================================
RCS file: /cvsroot/jboss/jboss-seam/examples/spring/src/org/jboss/seam/ioc/spring/SeamNamespaceHandler.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- SeamNamespaceHandler.java 15 Feb 2007 07:34:59 -0000 1.2
+++ SeamNamespaceHandler.java 16 Feb 2007 22:43:24 -0000 1.3
@@ -1,37 +1,176 @@
package org.jboss.seam.ioc.spring;
+import org.jboss.seam.InterceptionType;
+import org.jboss.seam.ScopeType;
+import org.springframework.beans.factory.BeanDefinitionStoreException;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.BeanDefinitionHolder;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
+import org.springframework.beans.factory.xml.BeanDefinitionDecorator;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.core.Ordered;
+import org.springframework.util.ClassUtils;
import org.w3c.dom.Element;
+import org.w3c.dom.Node;
/**
+ * NamespaceHandler for a number of seam features in spring.
+ *
* @author youngm
*/
public class SeamNamespaceHandler
extends NamespaceHandlerSupport
{
+ public static final String SEAM_SCOPE_POST_PROCESSOR = "org.jboss.seam.ioc.spring.SeamScopePostProcessor";
+
+ public static final String SEAM_COMPONENT_POST_PROCESSOR = "org.jboss.seam.ioc.spring.SeamComponentPostProcessor";
+
+ public static final String SEAM_COMPONENT_POST_PROCESSOR_BEAN_NAME = "org.jboss.seam.ioc.spring.seamComponentPostProcessor";
+
/**
* @see org.springframework.beans.factory.xml.NamespaceHandler#init()
*/
- public void init()
- {
- registerBeanDefinitionParser("instance", new SeamBeanBeanDefinitionParser());
+ public void init() {
+ registerBeanDefinitionParser("configure-scopes", new SeamConfigureScopeParser());
+ registerBeanDefinitionParser("instance", new SeamInstanceBeanDefinitionParser());
+ registerBeanDefinitionDecorator("component", new SeamComponentBeanDefinitionDecorator());
}
- private static class SeamBeanBeanDefinitionParser
+ /**
+ * Registers the SeamScopePostProcessor in this bean factory under
+ * the name defined in SEAM_SCOPE_POST_PROCESSOR.
+ * <seam:configure-scope/>
+ *
+ * @see SeamScopePostProcessor
+ * @author youngm
+ */
+ private static class SeamConfigureScopeParser
extends AbstractSimpleBeanDefinitionParser
{
+ /**
+ * @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#getBeanClass(org.w3c.dom.Element)
+ */
+ @Override
+ protected Class getBeanClass(Element element) {
+ return SeamScopePostProcessor.class;
+ }
- protected Class getBeanClass(Element element)
+ /**
+ * @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#resolveId(org.w3c.dom.Element,
+ * org.springframework.beans.factory.support.AbstractBeanDefinition,
+ * org.springframework.beans.factory.xml.ParserContext)
+ */
+ @Override
+ protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
+ throws BeanDefinitionStoreException
{
- return SeamFactoryBean.class;
+ return SEAM_SCOPE_POST_PROCESSOR;
+ }
}
- /*
- protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) {
- String id = super.resolveId(element, definition, parserContext);
- return id;
+ /**
+ * Makes a SeamFactoryBean available for use in a spring ApplicationContext. <seam:instance
+ * name="someSeamComponent"/>
+ *
+ * @see SeamFactoryBean
+ * @author youngm
+ */
+ private static class SeamInstanceBeanDefinitionParser
+ extends AbstractSimpleBeanDefinitionParser
+ {
+ protected Class getBeanClass(Element element) {
+ return SeamFactoryBean.class;
}
+ }
+
+ /**
+ * Makes an existing spring bean definition a seam component or
+ * provides hints in the creation of a seam component. Will use
+ * the bean definitions name and class by default and the classes
+ * annotatated InterceptionType.
+ *
+ * If proxy=true will wrap the spring bean in a cglib proxy for
+ * safe injection into singletons.
+ *
+ * <seam:component/>
+ *
+ * @author youngm
+ */
+ private static class SeamComponentBeanDefinitionDecorator implements BeanDefinitionDecorator {
+ private static final String INTERCEPT_ATTR = "intercept";
+ private static final String SPRING_NAME_ATTR = "springName";
+ private static final String SEAM_NAME_ATTR = "seamName";
+ private static final String BEAN_CLASS_ATTR = "beanClass";
+ public static final String AUTO_INTERCEPTION_TYPE = "AUTO";
+
+ /**
+ * @see org.springframework.beans.factory.xml.BeanDefinitionDecorator#decorate(org.w3c.dom.Node,
+ * org.springframework.beans.factory.config.BeanDefinitionHolder,
+ * org.springframework.beans.factory.xml.ParserContext)
*/
+ public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) {
+ // Add the Seam Component Post Processor to the bean factory if it doesn't already exist
+ if (!parserContext.getRegistry().containsBeanDefinition(SEAM_COMPONENT_POST_PROCESSOR_BEAN_NAME)) {
+ Class cls = null;
+ try {
+ cls = ClassUtils.forName(SEAM_COMPONENT_POST_PROCESSOR);
+ } catch (ClassNotFoundException e) {
+ throw new IllegalStateException("Unable to load class '" + SEAM_COMPONENT_POST_PROCESSOR
+ + "' make sure you have the jboss-seam-spring.jar in your classpath.");
+ }
+ RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
+ beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+ beanDefinition.getPropertyValues().addPropertyValue("order", new Integer(Ordered.LOWEST_PRECEDENCE));
+ parserContext.getRegistry().registerBeanDefinition(SEAM_COMPONENT_POST_PROCESSOR_BEAN_NAME,
+ beanDefinition);
+ }
+ // get the optional beanClass
+ String beanClassName = definition.getBeanDefinition().getBeanClassName();
+ if (node.getAttributes().getNamedItem(BEAN_CLASS_ATTR) != null) {
+ beanClassName = node.getAttributes().getNamedItem(BEAN_CLASS_ATTR).getNodeValue();
+ }
+ String beanName = definition.getBeanName();
+ // get the name of the seam component to create
+ String seamName = beanName;
+ if (node.getAttributes().getNamedItem(SEAM_NAME_ATTR) != null) {
+ seamName = node.getAttributes().getNamedItem(SEAM_NAME_ATTR).getNodeValue();
+ }
+ // get the name of the spring bean to use
+ String springName = beanName;
+ if (node.getAttributes().getNamedItem(SPRING_NAME_ATTR) != null) {
+ springName = node.getAttributes().getNamedItem(SPRING_NAME_ATTR).getNodeValue();
+ }
+ // get the interception type to use
+ InterceptionType interceptionType = null;
+ if (AUTO_INTERCEPTION_TYPE.equals(node.getAttributes().getNamedItem(INTERCEPT_ATTR).getNodeValue())) {
+ if (definition.getBeanDefinition().isSingleton()) {
+ interceptionType = InterceptionType.NEVER;
+ }
+ } else {
+ interceptionType = InterceptionType.valueOf(node.getAttributes().getNamedItem(INTERCEPT_ATTR)
+ .getNodeValue());
+ }
+
+ // get the requested scope
+ ScopeType scope = ScopeType.valueOf(node.getAttributes().getNamedItem("scope").getNodeValue());
+ if (scope != ScopeType.STATELESS
+ && !BeanDefinition.SCOPE_PROTOTYPE.equals(definition.getBeanDefinition().getScope())) {
+ throw new IllegalStateException(
+ "The spring bean scope must be prototype to use a seam scope other than STATELESS.");
+ }
+ // determine if we want to override any existing seam component definitions
+ boolean override = Boolean.parseBoolean(node.getAttributes().getNamedItem("override").getNodeValue());
+
+ if (!(parserContext.getRegistry() instanceof BeanFactory)) {
+ throw new RuntimeException("For some reason your registry is not a BeanFactory");
+ }
+ SpringComponent.addSpringComponent(seamName, springName, beanClassName, scope, (BeanFactory) parserContext
+ .getRegistry(), interceptionType, override);
+ return definition;
+ }
}
}
1.2 +74 -86 jboss-seam/examples/spring/src/org/jboss/seam/ioc/spring/SeamScope.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: SeamScope.java
===================================================================
RCS file: /cvsroot/jboss/jboss-seam/examples/spring/src/org/jboss/seam/ioc/spring/SeamScope.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- SeamScope.java 9 Feb 2007 17:37:18 -0000 1.1
+++ SeamScope.java 16 Feb 2007 22:43:24 -0000 1.2
@@ -2,7 +2,6 @@
import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
-import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.core.Events;
import org.jboss.seam.log.LogProvider;
import org.jboss.seam.log.Logging;
@@ -10,41 +9,38 @@
import org.springframework.beans.factory.config.Scope;
/**
- * Allows for the creation of seam scoped component in spring. Seam scopes are
- * automatically made available if the SeamPostProcessor is declared in the
- * current BeanFactory.
+ * Allows for the creation of seam scoped component in spring. Seam
+ * scopes are automatically made available if the
+ * SeamScopePostProcessor is declared in the current
+ * BeanFactory. <seam:configure-scopes/>
*
* @author youngm
- * @see SeamPostProcessor
+ * @see SeamScopePostProcessor
*/
-public class SeamScope implements Scope
+public class SeamScope
+ implements Scope
{
private static final LogProvider log = Logging.getLogProvider(SeamScope.class);
private ScopeType scope;
- public SeamScope(ScopeType scope)
- {
+ public SeamScope(ScopeType scope) {
this.scope = scope;
}
/**
- * Gets an instance of a Seam component providing the current ObjectFactory
- * if needed.
+ * Gets an instance of a Seam component providing the current ObjectFactory if needed.
*
* @see org.springframework.beans.factory.config.Scope#get(java.lang.String,
- *org.springframework.beans.factory.ObjectFactory)
+ * org.springframework.beans.factory.ObjectFactory)
*/
- public Object get(String name, ObjectFactory objectFactory)
- {
- try
- {
- SpringComponent.setFactoryBean(objectFactory);
- return Component.getInstance(name, scope);
- }
- finally
- {
- SpringComponent.setFactoryBean(null);
+ public Object get(String name, ObjectFactory objectFactory) {
+ try {
+ SpringComponent.setObjectFactory(objectFactory);
+ Component component = SpringComponent.forSpringBeanName(name);
+ return Component.getInstance(component.getName(), scope, true);
+ } finally {
+ SpringComponent.setObjectFactory(null);
}
}
@@ -53,18 +49,16 @@
*
* @see org.springframework.beans.factory.config.Scope#getConversationId()
*/
- public String getConversationId()
- {
+ public String getConversationId() {
return null;
}
/**
* @see org.springframework.beans.factory.config.Scope#registerDestructionCallback(java.lang.String,
- *java.lang.Runnable)
+ * java.lang.Runnable)
*/
- public void registerDestructionCallback(String name, Runnable callback)
- {
- ((SpringComponent)Component.forName(name)).registerDestroyCallback(name, callback);
+ public void registerDestructionCallback(String name, Runnable callback) {
+ ((SpringComponent) SpringComponent.forSpringBeanName(name)).registerDestroyCallback(name, callback);
}
/**
@@ -72,32 +66,26 @@
*
* @see org.springframework.beans.factory.config.Scope#remove(java.lang.String)
*/
- public Object remove(String name)
- {
+ public Object remove(String name) {
+ // copied from Component.callDestory should be able to reuse. Needed because if remove is called then for some
+ // reason spring doesn't use the destroy callback.
log.debug("destroying: " + name);
- Component component = Component.forName(name);
- Object bean = scope.getContext().get(name);
- if (component != null)
- {
- if (bean != null) // in a portal environment, this is possible
- {
+ Component component = SpringComponent.forSpringBeanName(name);
+ Object bean = scope.getContext().get(component.getName());
+ if (component != null) {
+ if (bean != null) { // in a portal environment, this is possible
if (Events.exists())
Events.instance().raiseEvent("org.jboss.seam.preDestroy." + name);
- try
- {
- if (component.hasDestroyMethod())
- {
+ try {
+ if (component.hasDestroyMethod()) {
component.callComponentMethod(bean, component.getDestroyMethod());
}
+ } catch (Exception e) {
+ log.warn("Could not destroy component: " + component.getName(), e);
}
- catch (Exception e)
- {
- log.warn("Could not destroy component: " + name, e);
}
}
- }
- Contexts.getEventContext().remove(name);
+ scope.getContext().remove(component.getName());
return bean;
}
-
}
1.2 +233 -83 jboss-seam/examples/spring/src/org/jboss/seam/ioc/spring/SpringComponent.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: SpringComponent.java
===================================================================
RCS file: /cvsroot/jboss/jboss-seam/examples/spring/src/org/jboss/seam/ioc/spring/SpringComponent.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- SpringComponent.java 9 Feb 2007 17:37:18 -0000 1.1
+++ SpringComponent.java 16 Feb 2007 22:43:24 -0000 1.2
@@ -1,63 +1,187 @@
package org.jboss.seam.ioc.spring;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.http.HttpSessionActivationListener;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.InterceptionType;
import org.jboss.seam.ScopeType;
+import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.contexts.Lifecycle;
+import org.jboss.seam.core.Mutable;
+import org.jboss.seam.init.Initialization;
+import org.jboss.seam.intercept.Proxy;
import org.jboss.seam.ioc.IoCComponent;
+import org.jboss.seam.ioc.ProxyUtils;
+import org.springframework.aop.framework.Advised;
+import org.springframework.beans.FatalBeanException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ObjectFactory;
+import org.springframework.util.ClassUtils;
/**
- * An extension of Component that allows spring to provide the base instance for
- * a seam component.
+ * An extension of Component that allows spring to provide the base instance for a seam component.
*
* @author youngm
*/
-public class SpringComponent extends IoCComponent
-{
+public class SpringComponent extends IoCComponent {
+ private static final String SPRING_COMPONENT_NAME_MAP = "org.jboss.seam.SpringComponentNameMap";
+
public static final String DESTRUCTION_CALLBACK_NAME_PREFIX = IoCComponent.class.getName()
+ ".DESTRUCTION_CALLBACK.";
private BeanFactory beanfactory;
- private static final ThreadLocal<ObjectFactory> factoryBean = new ThreadLocal<ObjectFactory>();
+ private InterceptionType interceptionType;
+
+ private String springBeanName;
+
+ private static final ThreadLocal<ObjectFactory> objectFactory = new ThreadLocal<ObjectFactory>();
+
+ public static ObjectFactory getObjectFactory() {
+ return objectFactory.get();
+ }
+
+ public static void setObjectFactory(ObjectFactory bean) {
+ objectFactory.set(bean);
+ }
/**
- * Creates a Spring Seam Component given a beanFactory.
+ * Utility to add a SpringComponent to the seam component ApplicationContext.
*
- * @param clazz class
- * @param name component name
- * @param scope component scope
- * @param factory factory
+ * @param componentName the seam component name to use
+ * @param springBeanName the spring bean name to map to this seam component
+ * @param beanClassName the seam beanClass to use
+ * @param scopeType the scope of this component
+ * @param beanFactory the beanfactory this spring bean exists in
+ * @param interceptorType the InterceptorTyp to force the bean to use. Will override any annotations on the bean.
+ * @param override If a seam component already exists should we override it?
*/
- public SpringComponent(Class clazz, String name, ScopeType scope, BeanFactory factory)
- {
- super(clazz, name, scope);
- this.beanfactory = factory;
+ public static void addSpringComponent(String componentName, String springBeanName, String beanClassName,
+ ScopeType scopeType, BeanFactory beanFactory, InterceptionType interceptorType, boolean override) {
+ // mock the application context
+ // TODO reuse
+ boolean unmockApplication = false;
+ if (!Contexts.isApplicationContextActive()) {
+ Lifecycle.mockApplication();
+ unmockApplication = true;
+ }
+ try {
+ if (!override && Component.forName(componentName) != null) {
+ throw new IllegalStateException("Cannot add spring component to seam with name: " + componentName
+ + ". There is already a seam component with that name.");
+ }
+ Map<String, String> springComponentNameMap = getSpringComponentNameMap();
+ // Add an entry to the spring+seam name association map
+ springComponentNameMap.put(springBeanName, componentName);
+ Class beanClass = ClassUtils.forName(beanClassName);
+ // Add the component to seam
+ Contexts.getApplicationContext().set(
+ componentName + Initialization.COMPONENT_SUFFIX,
+ new SpringComponent(beanClass, componentName, springBeanName, scopeType, beanFactory,
+ interceptorType));
+ } catch (ClassNotFoundException e) {
+ throw new FatalBeanException("Error", e);
+ } finally {
+ if (unmockApplication) {
+ Lifecycle.unmockApplication();
+ }
+ }
}
- public static ObjectFactory getFactoryBean()
- {
- return factoryBean.get();
+ @SuppressWarnings("unchecked")
+ private static Map<String, String> getSpringComponentNameMap() {
+ if (Contexts.getApplicationContext().get(SPRING_COMPONENT_NAME_MAP) == null) {
+ Contexts.getApplicationContext().set(SPRING_COMPONENT_NAME_MAP, new HashMap<String, String>());
+ }
+ return (Map<String, String>) Contexts.getApplicationContext().get(SPRING_COMPONENT_NAME_MAP);
}
- public static void setFactoryBean(ObjectFactory bean)
- {
- factoryBean.set(bean);
+ /**
+ * Just like Component.forName() but mocks the applicationContext and you provide it with the spring bean name
+ * instead of the seam component name.
+ *
+ * @param name the spring bean name.
+ * @return the SpringComponent mapped to that spring bean name.
+ */
+ public static SpringComponent forSpringBeanName(String springBeanName) {
+ // TODO reuse
+ boolean unmockApplication = false;
+ if (!Contexts.isApplicationContextActive()) {
+ Lifecycle.mockApplication();
+ unmockApplication = true;
+ }
+ try {
+ return (SpringComponent) Component.forName(getSpringComponentNameMap().get(springBeanName));
+ } finally {
+ if (unmockApplication) {
+ Lifecycle.unmockApplication();
+ }
+ }
}
- protected String getIoCName()
- {
+ /**
+ * Creates a Spring Seam Component given a beanFactory.
+ *
+ * @param clazz the seam beanClass to use
+ * @param componentName component name
+ * @param springBeanName the spring bean name
+ * @param scope component scope
+ * @param factory the beanfactory this spring component should use
+ */
+ public SpringComponent(Class clazz, String componenentName, String springBeanName, ScopeType scope,
+ BeanFactory factory, InterceptionType interception) {
+ super(clazz, componenentName, scope);
+ this.springBeanName = springBeanName;
+ this.beanfactory = factory;
+ this.interceptionType = interception;
+ }
+
+ protected String getIoCName() {
return "Spring";
}
- protected Object instantiateIoCBean() throws Exception
- {
- ObjectFactory objectFactory = getFactoryBean();
- if (objectFactory == null)
- {
- return beanfactory.getBean(getName());
+ protected Object instantiateIoCBean() throws Exception {
+ ObjectFactory objectFactory = getObjectFactory();
+ if (objectFactory == null) {
+ return beanfactory.getBean(springBeanName);
+ }
+ setObjectFactory(null);
+ Object bean = objectFactory.getObject();
+ // initialize the bean following Component.instantiateJavaBean()'s
+ // pattern.
+ if (getInterceptionType() == InterceptionType.NEVER) {
+ // Only call postConstruct if the bean is not stateless otherwise in the case of a singleton it wowuld be
+ // called every time seam request the bean not just when it is created.
+ if (getScope() != ScopeType.STATELESS) {
+ callPostConstructMethod(bean);
+ }
+ } else if (!(bean instanceof Proxy)) {
+ // Add all of the interfaces of the bean instance into the Seam
+ // proxy bean because spring's proxies add a bunch of interfaces too
+ // that should be accessible.
+ Set<Class> interfaces = new HashSet<Class>(Arrays.asList(bean.getClass().getInterfaces()));
+ interfaces.add(HttpSessionActivationListener.class);
+ interfaces.add(Mutable.class);
+ interfaces.add(Proxy.class);
+ // enhance bean
+ bean = ProxyUtils.enhance(bean, interfaces, this);
+ }
+ return bean;
}
- setFactoryBean(null);
- return objectFactory.getObject();
+
+ /**
+ * Instantiates a IoC bean and provides it as a java bean to be wrapped by seam.
+ *
+ * @see org.jboss.seam.Component#instantiateJavaBean()
+ */
+ protected Object instantiateJavaBean() throws Exception {
+ return instantiateIoCBean();
}
/**
@@ -66,15 +190,12 @@
* @see org.jboss.seam.Component#callDestroyMethod(Object)
*/
@Override
- public void callDestroyMethod(Object instance)
- {
+ public void callDestroyMethod(Object instance) {
super.callDestroyMethod(instance);
- // Cannot call the callback on a STATELESS bean
- if (getScope() != ScopeType.STATELESS)
- {
- Runnable callback = (Runnable)getScope().getContext().get(DESTRUCTION_CALLBACK_NAME_PREFIX + getName());
- if (callback != null)
- {
+ // Cannot call the callback on a STATELESS bean because we have no way of storing it.
+ if (getScope() != ScopeType.STATELESS) {
+ Runnable callback = (Runnable) getScope().getContext().get(DESTRUCTION_CALLBACK_NAME_PREFIX + getName());
+ if (callback != null) {
callback.run();
}
}
@@ -86,13 +207,42 @@
* @param name bean name
* @param destroy the destroy to set
*/
- public void registerDestroyCallback(String name, Runnable destroy)
- {
+ public void registerDestroyCallback(String name, Runnable destroy) {
// Not sure yet how to register a stateless bean's Destruction callback.
- if (getScope() != ScopeType.STATELESS)
- {
+ if (getScope() != ScopeType.STATELESS) {
getScope().getContext().set(DESTRUCTION_CALLBACK_NAME_PREFIX + name, destroy);
}
}
+ /**
+ * Overrides Components inject to unwrap all of the spring AOP layers so that fields can be injected into this bean.
+ *
+ * @see org.jboss.seam.Component#inject(java.lang.Object, boolean)
+ */
+ @Override
+ public void inject(Object bean, boolean enforceRequired) {
+ if (bean instanceof Advised) {
+ try {
+ inject(((Advised) bean).getTargetSource().getTarget(), enforceRequired);
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ super.inject(bean, enforceRequired);
+ }
+
+ /**
+ * Use the InterceptionType override if available otherwise use the annotation or seam default.
+ *
+ * @see org.jboss.seam.Component#getInterceptionType()
+ */
+ @Override
+ public InterceptionType getInterceptionType() {
+ if (interceptionType == null) {
+ return super.getInterceptionType();
+ }
+ return interceptionType;
+ }
}
1.2 +210 -43 jboss-seam/examples/spring/src/org/jboss/seam/ioc/spring/spring.xsd
(In the diff below, changes in quantity of whitespace are not shown.)
Index: spring.xsd
===================================================================
RCS file: /cvsroot/jboss/jboss-seam/examples/spring/src/org/jboss/seam/ioc/spring/spring.xsd,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- spring.xsd 9 Feb 2007 17:37:18 -0000 1.1
+++ spring.xsd 16 Feb 2007 22:43:24 -0000 1.2
@@ -1,43 +1,210 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://jboss.com/products/seam/spring" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
- xmlns:tool="http://www.springframework.org/schema/tool"
- targetNamespace="http://jboss.com/products/seam/spring"
- elementFormDefault="qualified" attributeFormDefault="unqualified">
+ xmlns:tool="http://www.springframework.org/schema/tool" targetNamespace="http://jboss.com/products/seam/spring"
+ elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:p="http://icslib.wh.ldsglobal.net/schema/ldsutil">
<xsd:import namespace="http://www.springframework.org/schema/tool"
- schemaLocation="http://www.springframework.org/schema/tool/spring-tool-2.0.xsd"/>
+ schemaLocation="http://www.springframework.org/schema/tool/spring-tool-2.0.xsd" />
+ <xsd:element name="configure-scopes">
+ <xsd:annotation>
+ <xsd:documentation>Makes all the seam scopes available in spring.</xsd:documentation>
+ <xsd:appinfo>
+ <tool:annotation>
+ <tool:exports />
+ </tool:annotation>
+ </xsd:appinfo>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:attribute name="prefix" type="xsd:string" use="optional">
+ <xsd:annotation>
+ <xsd:documentation>
+ <![CDATA[
+ The prefix to use for the seam scopes. Default: "seam."
+ ]]>
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="override" type="xsd:boolean" use="optional" default="false">
+ <xsd:annotation>
+ <xsd:documentation>
+ <![CDATA[
+ If a duplicate is found should it override it or throw an error? Default: false
+ ]]>
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+ </xsd:element>
<xsd:element name="instance">
<xsd:annotation>
<xsd:documentation>
- Obtains an instance of a seam
+ Make an instance of a seam component available to spring beans for spring injection.
</xsd:documentation>
-
<xsd:appinfo>
<tool:annotation>
- <tool:exports/>
+ <tool:exports />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
- <xsd:attribute name="id" type="xsd:ID"/>
- <xsd:attribute name="name" type="xsd:string" use="required"/>
+ <xsd:attribute name="id" type="xsd:ID">
+ <xsd:annotation>
+ <xsd:documentation>
+ <![CDATA[
+ The id to use when making this seam component instance available in spring. The default will be the seam component name.
+ ]]>
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="name" type="xsd:string" use="required">
+ <xsd:annotation>
+ <xsd:documentation>
+ <![CDATA[
+ The seam component name to get an instance of.
+ ]]>
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
<xsd:attribute name="scope" use="optional">
+ <xsd:annotation>
+ <xsd:documentation>
+ <![CDATA[
+ The optional scope to look for this seam component instance in.
+ ]]>
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="STATELESS" />
+ <xsd:enumeration value="METHOD" />
+ <xsd:enumeration value="EVENT" />
+ <xsd:enumeration value="PAGE" />
+ <xsd:enumeration value="CONVERSATION" />
+ <xsd:enumeration value="SESSION" />
+ <xsd:enumeration value="APPLICATION" />
+ <xsd:enumeration value="BUSINESS_PROCESS" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+ <xsd:attribute name="create" type="xsd:boolean" use="optional">
+ <xsd:annotation>
+ <xsd:documentation>
+ <![CDATA[
+ Whether seam should create a new instance if one does not already exist.
+ ]]>
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="proxy" type="xsd:boolean" use="optional" default="false">
+ <xsd:annotation>
+ <xsd:documentation>
+ <![CDATA[
+ Whether to wrap this definition in a proxy for safe injection into a spring singleton.
+ ]]>
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="component">
+ <xsd:annotation>
+ <xsd:documentation>
+ <![CDATA[
+ Makes the surrounding spring bean a seam component with the scope managed by spring. Also helps to resolve cases where
+ the spring bean name must be different from the seam component name or where the seam beanClass cannot be correctly
+ detected.
+ ]]>
+ </xsd:documentation>
+ <xsd:appinfo>
+ <tool:annotation>
+ <tool:exports />
+ </tool:annotation>
+ </xsd:appinfo>
+ </xsd:annotation>
+ <xsd:complexType>
+ <xsd:attribute name="seamName" type="xsd:string" use="optional">
+ <xsd:annotation>
+ <xsd:documentation>
+ <![CDATA[
+ The seam component name to give this spring bean. Optional unless the seam component name must be different from the
+ spring bean name.
+ ]]>
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="springName" type="xsd:string" use="optional">
+ <xsd:annotation>
+ <xsd:documentation>
+ <![CDATA[
+ What spring bean name should seam use to obtain an instance of this bean. Only necessary when spring-seam cannot
+ property detect the name of the spring bean which some spring NamespaceHandlers can do (eg. <aop:scoped-proxy/>, etc.).
+ ]]>
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="beanClass" type="xsd:string" use="optional">
+ <xsd:annotation>
+ <xsd:documentation source="java:java.lang.Class">
+ <![CDATA[
+ The component beanClass seam will use to get annotations from and to wrap it's interceptors around. Optional unless the
+ correct class is not being detected seam-spring.
+ ]]>
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="intercept" use="optional" default="AUTO">
+ <xsd:annotation>
+ <xsd:documentation source="java:java.lang.Class">
+ <![CDATA[
+ Overrides the default InterceptionType seam uses when determining if it's interceptors should be wrapped around a bean.
+ Seldom do you want the seam interceptors wrapped around a sprig singleton. Auto will use choose NEVER for a singleton
+ and use seam standard rules otherwise.
+ ]]>
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="AUTO" />
+ <xsd:enumeration value="NEVER" />
+ <xsd:enumeration value="AFTER_RESTORE_VIEW" />
+ <xsd:enumeration value="AFTER_UPDATE_MODEL_VALUES" />
+ <xsd:enumeration value="INVOKE_APPLICATION" />
+ <xsd:enumeration value="ALWAYS" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+ <xsd:attribute name="override" type="xsd:boolean" use="optional" default="false">
+ <xsd:annotation>
+ <xsd:documentation>
+ <![CDATA[
+ If a duplicate is found should it override it or throw an error? Default: false
+ ]]>
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:attribute>
+ <xsd:attribute name="scope" use="optional" default="STATELESS">
+ <xsd:annotation>
+ <xsd:documentation>
+ <![CDATA[
+The optional scope this component should have. STATELESS will allow spring to manage the scope.
+ ]]>
+ </xsd:documentation>
+ </xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:string">
- <xsd:enumeration value="STATELESS"/>
- <xsd:enumeration value="METHOD"/>
- <xsd:enumeration value="EVENT"/>
- <xsd:enumeration value="PAGE"/>
- <xsd:enumeration value="CONVERSATION"/>
- <xsd:enumeration value="SESSION"/>
- <xsd:enumeration value="APPLICATION"/>
- <xsd:enumeration value="BUSINESS_PROCESS"/>
+ <xsd:enumeration value="STATELESS" />
+ <xsd:enumeration value="METHOD" />
+ <xsd:enumeration value="EVENT" />
+ <xsd:enumeration value="PAGE" />
+ <xsd:enumeration value="CONVERSATION" />
+ <xsd:enumeration value="SESSION" />
+ <xsd:enumeration value="APPLICATION" />
+ <xsd:enumeration value="BUSINESS_PROCESS" />
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
- <xsd:attribute name="create" type="xsd:boolean" use="optional"/>
</xsd:complexType>
</xsd:element>
</xsd:schema>
\ No newline at end of file
1.1 date: 2007/02/16 22:43:24; author: nrichards; state: Exp;jboss-seam/examples/spring/src/org/jboss/seam/ioc/spring/SeamComponentPostProcessor.java
Index: SeamComponentPostProcessor.java
===================================================================
package org.jboss.seam.ioc.spring;
import org.jboss.seam.Component;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;
/**
* Intercepts when spring attempts to obtain an instance of a bean. If the bean is a seam component then we retrieve the
* bean from seam to ensure it gets wrapped and managed by seam as well. This post processor must have a lower
* precedence than any spring autoproxy creators.
*
* @author youngm
*/
public class SeamComponentPostProcessor implements BeanPostProcessor, Ordered {
private int order = Ordered.LOWEST_PRECEDENCE;
/**
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object,
* java.lang.String)
*/
public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
// Check to see if this bean is a component.
Component component = SpringComponent.forSpringBeanName(beanName);
// Not a spring component skip.
if (component == null || !(component instanceof SpringComponent)) {
return bean;
}
// If this bean is a FactoryBean only request the bean from Seam if the component is a FactoryBean as well
// The object created by the factory should come along later
if (bean instanceof FactoryBean && !FactoryBean.class.isAssignableFrom(component.getBeanClass())) {
return bean;
}
// Wrap our bean instance in an object factory for the SpringComponent to use
SpringComponent.setObjectFactory(new ObjectFactory() {
public Object getObject() throws BeansException {
return bean;
}
});
// Return the seam instance
return Component.getInstance(beanName, component.getScope());
}
/**
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object,
* java.lang.String)
*/
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
/**
* This post processor must run after any spring AutoProxyCreator
*
* @see org.springframework.core.Ordered#getOrder()
*/
public int getOrder() {
return order;
}
/**
* @param order the order to set
*/
public void setOrder(int order) {
this.order = order;
}
}
1.1 date: 2007/02/16 22:43:24; author: nrichards; state: Exp;jboss-seam/examples/spring/src/org/jboss/seam/ioc/spring/SeamScopePostProcessor.java
Index: SeamScopePostProcessor.java
===================================================================
package org.jboss.seam.ioc.spring;
import org.jboss.seam.ScopeType;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.contexts.Lifecycle;
import org.jboss.seam.log.LogProvider;
import org.jboss.seam.log.Logging;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
/**
* Post processor that makes all of the seam scopes available in
* spring and takes all of the beans with those scopes and creates
* Seam Components out of them. <p/> To use simply define the
* namespace hanlder in in your ApplicationContext.
* <seam:configure-scopes/>
*
* @author youngm
*/
public class SeamScopePostProcessor
implements BeanFactoryPostProcessor,
InitializingBean
{
private static final LogProvider log = Logging.getLogProvider(SeamScopePostProcessor.class);
/**
* Default seam scope prefix.
*/
public static final String DEFAULT_SCOPE_PREFIX = "seam.";
private String prefix;
private boolean override = false;
/**
* Null is not a valid prefix so make it the default is used if null or empty.
*
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
public void afterPropertiesSet() throws Exception {
if (prefix == null || "".equals(prefix)) {
prefix = DEFAULT_SCOPE_PREFIX;
}
}
/**
* Add all of the seam scopes to this beanFactory.
*
* @see org.springframework.beans.factory.config.BeanFactoryPostProcessor#postProcessBeanFactory(org.springframework.beans.factory.config.ConfigurableListableBeanFactory)
*/
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException
{
for (ScopeType scope : ScopeType.values()) {
// Don't create a scope for Unspecified
if (scope != ScopeType.UNSPECIFIED) {
beanFactory.registerScope(prefix + scope.name(), new SeamScope(scope));
}
}
// Create a mock application context if not available.
// TODO Reuse
boolean unmockApplication = false;
if (!Contexts.isApplicationContextActive()) {
Lifecycle.mockApplication();
unmockApplication = true;
}
try {
// Iterate through all the beans in the factory
for (String beanName : beanFactory.getBeanDefinitionNames()) {
BeanDefinition definition = beanFactory.getBeanDefinition(beanName);
ScopeType scope;
if (definition.getScope().startsWith(prefix)) {
// Will throw an error if the scope is not found.
scope = ScopeType.valueOf(definition.getScope().replaceFirst(prefix, "").toUpperCase());
} else {
if (log.isDebugEnabled()) {
log.debug("No scope could be derived for bean with name: " + beanName);
}
continue;
}
if (scope == ScopeType.UNSPECIFIED) {
if (log.isDebugEnabled()) {
log.debug("Discarding bean with scope UNSPECIFIED. Spring will throw an error later: "
+ beanName);
}
continue;
}
// Cannot be a seam component without a specified class seam:component will need to be used for this
// bean.
if (definition.getBeanClassName() == null) {
if (log.isDebugEnabled()) {
log.debug("Unable to create component for bean: " + beanName
+ ". No class defined try seam:component instead.");
}
continue;
}
SpringComponent.addSpringComponent(beanName, beanName, definition.getBeanClassName(), scope, beanFactory, null,
override);
}
} finally {
if (unmockApplication) {
Lifecycle.unmockApplication();
}
}
}
/**
* @param casesensitive prefix the prefix to use to identify seam scopes for spring beans. Default is "seam."
*/
public void setPrefix(String prefix) {
this.prefix = prefix;
}
/**
* @param duplicate set to tell the postprocessor to duplicate any preexisting seam components that may have the same
* name as the candidate spring bean. Default: false
*/
public void setOverride(boolean override) {
this.override = override;
}
}
1.1 date: 2007/02/16 22:43:24; author: nrichards; state: Exp;jboss-seam/examples/spring/src/org/jboss/seam/ioc/spring/SeamTargetSource.java
Index: SeamTargetSource.java
===================================================================
package org.jboss.seam.ioc.spring;
import java.io.Serializable;
import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.contexts.Lifecycle;
import org.jboss.seam.log.LogProvider;
import org.jboss.seam.log.Logging;
import org.springframework.aop.TargetSource;
/**
* A TargetSource for a seam component instance. Will obtain an instance given a name and optionally a scope and create.
* Used by the SeamFactoryBean to create a proxy for a requested seam component instance.
*
* @author youngm
*/
@SuppressWarnings("serial")
public class SeamTargetSource implements TargetSource, Serializable {
private static final LogProvider log = Logging.getLogProvider(SeamTargetSource.class);
private ScopeType scope;
private String name;
private Boolean create;
/**
* @param name Name of the component: required
* @param scope Name of the scope the component is in: optional
* @param create Whether to create a new instance if one doesn't already exist: optional
*/
public SeamTargetSource(String name, ScopeType scope, Boolean create) {
if (name == null || "".equals(name)) {
throw new IllegalArgumentException("Name is required.");
}
this.name = name;
this.scope = scope;
this.create = create;
}
/**
* Returns a component instance for this TargetSource.
*
* @see org.springframework.aop.TargetSource#getTarget()
*/
public Object getTarget() throws Exception {
if (scope == null && create == null) {
return Component.getInstance(name);
} else if (scope == null) {
return Component.getInstance(name, create);
} else if (create == null) {
return Component.getInstance(name, scope);
} else {
return Component.getInstance(name, scope, create);
}
}
/**
* Obtains the seam component beanClass for this TargetSource.
*
* @see org.springframework.aop.TargetSource#getTargetClass()
*/
public Class getTargetClass() {
return getComponent().getBeanClass();
}
/**
* Get the component for this TargetSource
*
* @return
*/
public Component getComponent() {
// TODO reuse
boolean unmockApplication = false;
if (!Contexts.isApplicationContextActive()) {
Lifecycle.mockApplication();
unmockApplication = true;
}
try {
Component component = Component.forName(name);
if (component == null) {
throw new IllegalStateException("Cannot find targetClass for seam component: " + name
+ ". Make sure Seam is being configured before Spring.");
}
return component;
} finally {
if (unmockApplication) {
Lifecycle.unmockApplication();
}
}
}
/**
* @see org.springframework.aop.TargetSource#isStatic()
*/
public boolean isStatic() {
return false;
}
/**
* Don't think we need to do anything here.
*
* @see org.springframework.aop.TargetSource#releaseTarget(java.lang.Object)
*/
public void releaseTarget(Object target) throws Exception {
// Do Nothing
}
}
1.1 date: 2007/02/16 22:43:24; author: nrichards; state: Exp;jboss-seam/examples/spring/src/org/jboss/seam/ioc/spring/TestAnnotation.java
Index: TestAnnotation.java
===================================================================
/**
*
*/
package org.jboss.seam.example.spring;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* @author youngm
*
*/
@Target({TYPE})
@Retention(RUNTIME)
public @interface TestAnnotation {
}
1.1 date: 2007/02/16 22:43:24; author: nrichards; state: Exp;jboss-seam/examples/spring/src/org/jboss/seam/ioc/spring/TestInterceptor.java
Index: TestInterceptor.java
===================================================================
/**
*
*/
package org.jboss.seam.example.spring;
import java.io.Serializable;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/**
* @author youngm
*
*/
public class TestInterceptor implements MethodInterceptor, Serializable {
/**
* @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
*/
public Object invoke(MethodInvocation arg0) throws Throwable {
System.out.println("Hit interceptor");
return arg0.proceed();
}
}
More information about the jboss-cvs-commits
mailing list