Drop outdated BeanFactoryLocator / beanRefContext.xml mechanism

Issue: SPR-15154
This commit is contained in:
Juergen Hoeller
2017-01-17 13:58:37 +01:00
parent d96738d613
commit ac6aa53031
30 changed files with 74 additions and 2388 deletions

View File

@@ -1,77 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.context.access;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.access.BeanFactoryReference;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
/**
* ApplicationContext-specific implementation of BeanFactoryReference,
* wrapping a newly created ApplicationContext, closing it on release.
*
* <p>As per BeanFactoryReference contract, {@code release} may be called
* more than once, with subsequent calls not doing anything. However, calling
* {@code getFactory} after a {@code release} call will cause an exception.
*
* @author Juergen Hoeller
* @author Colin Sampaleanu
* @since 13.02.2004
* @see org.springframework.context.ConfigurableApplicationContext#close
*/
public class ContextBeanFactoryReference implements BeanFactoryReference {
private ApplicationContext applicationContext;
/**
* Create a new ContextBeanFactoryReference for the given context.
* @param applicationContext the ApplicationContext to wrap
*/
public ContextBeanFactoryReference(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Override
public BeanFactory getFactory() {
if (this.applicationContext == null) {
throw new IllegalStateException(
"ApplicationContext owned by this BeanFactoryReference has been released");
}
return this.applicationContext;
}
@Override
public void release() {
if (this.applicationContext != null) {
ApplicationContext savedCtx;
// We don't actually guarantee thread-safety, but it's not a lot of extra work.
synchronized (this) {
savedCtx = this.applicationContext;
this.applicationContext = null;
}
if (savedCtx != null && savedCtx instanceof ConfigurableApplicationContext) {
((ConfigurableApplicationContext) savedCtx).close();
}
}
}
}

View File

@@ -1,106 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.context.access;
import javax.naming.NamingException;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.access.BeanFactoryLocator;
import org.springframework.beans.factory.access.BeanFactoryReference;
import org.springframework.beans.factory.access.BootstrapException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jndi.JndiLocatorSupport;
import org.springframework.util.StringUtils;
/**
* BeanFactoryLocator implementation that creates the BeanFactory from one or
* more classpath locations specified in a JNDI environment variable.
*
* <p>This default implementation creates a
* {@link org.springframework.context.support.ClassPathXmlApplicationContext}.
* Subclasses may override {@link #createBeanFactory} for custom instantiation.
*
* @author Colin Sampaleanu
* @author Juergen Hoeller
* @see #createBeanFactory
*/
public class ContextJndiBeanFactoryLocator extends JndiLocatorSupport implements BeanFactoryLocator {
/**
* Any number of these characters are considered delimiters between
* multiple bean factory config paths in a single String value.
*/
public static final String BEAN_FACTORY_PATH_DELIMITERS = ",; \t\n";
/**
* Load/use a bean factory, as specified by a factory key which is a JNDI
* address, of the form {@code java:comp/env/ejb/BeanFactoryPath}. The
* contents of this JNDI location must be a string containing one or more
* classpath resource names (separated by any of the delimiters '{@code ,; \t\n}'
* if there is more than one. The resulting BeanFactory (or ApplicationContext)
* will be created from the combined resources.
* @see #createBeanFactory
*/
@Override
public BeanFactoryReference useBeanFactory(String factoryKey) throws BeansException {
try {
String beanFactoryPath = lookup(factoryKey, String.class);
if (logger.isTraceEnabled()) {
logger.trace("Bean factory path from JNDI environment variable [" + factoryKey +
"] is: " + beanFactoryPath);
}
String[] paths = StringUtils.tokenizeToStringArray(beanFactoryPath, BEAN_FACTORY_PATH_DELIMITERS);
return createBeanFactory(paths);
}
catch (NamingException ex) {
throw new BootstrapException("Define an environment variable [" + factoryKey + "] containing " +
"the class path locations of XML bean definition files", ex);
}
}
/**
* Create the BeanFactory instance, given an array of class path resource Strings
* which should be combined. This is split out as a separate method so that
* subclasses can override the actual BeanFactory implementation class.
* <p>Delegates to {@code createApplicationContext} by default,
* wrapping the result in a ContextBeanFactoryReference.
* @param resources an array of Strings representing classpath resource names
* @return the created BeanFactory, wrapped in a BeanFactoryReference
* (for example, a ContextBeanFactoryReference wrapping an ApplicationContext)
* @throws BeansException if factory creation failed
* @see #createApplicationContext
* @see ContextBeanFactoryReference
*/
protected BeanFactoryReference createBeanFactory(String[] resources) throws BeansException {
ApplicationContext ctx = createApplicationContext(resources);
return new ContextBeanFactoryReference(ctx);
}
/**
* Create the ApplicationContext instance, given an array of class path resource
* Strings which should be combined
* @param resources an array of Strings representing classpath resource names
* @return the created ApplicationContext
* @throws BeansException if context creation failed
*/
protected ApplicationContext createApplicationContext(String[] resources) throws BeansException {
return new ClassPathXmlApplicationContext(resources);
}
}

View File

@@ -1,162 +0,0 @@
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.context.access;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.access.BeanFactoryLocator;
import org.springframework.beans.factory.access.SingletonBeanFactoryLocator;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternUtils;
/**
* <p>Variant of {@link org.springframework.beans.factory.access.SingletonBeanFactoryLocator}
* which creates its internal bean factory reference as an
* {@link org.springframework.context.ApplicationContext} instead of
* SingletonBeanFactoryLocator's simple BeanFactory. For almost all usage scenarios,
* this will not make a difference, since within that ApplicationContext or BeanFactory
* you are still free to define either BeanFactory or ApplicationContext instances.
* The main reason one would need to use this class is if bean post-processing
* (or other ApplicationContext specific features are needed in the bean reference
* definition itself).
*
* <p><strong>Note:</strong> This class uses <strong>classpath*:beanRefContext.xml</strong>
* as the default resource location for the bean factory reference definition files.
* It is not possible nor legal to share definitions with SingletonBeanFactoryLocator
* at the same time.
*
* @author Colin Sampaleanu
* @author Juergen Hoeller
* @see org.springframework.beans.factory.access.SingletonBeanFactoryLocator
* @see org.springframework.context.access.DefaultLocatorFactory
*/
public class ContextSingletonBeanFactoryLocator extends SingletonBeanFactoryLocator {
private static final String DEFAULT_RESOURCE_LOCATION = "classpath*:beanRefContext.xml";
/** The keyed singleton instances */
private static final Map<String, BeanFactoryLocator> instances = new HashMap<>();
/**
* Returns an instance which uses the default "classpath*:beanRefContext.xml", as
* the name of the definition file(s). All resources returned by the current
* thread's context class loader's {@code getResources} method with this
* name will be combined to create a definition, which is just a BeanFactory.
* @return the corresponding BeanFactoryLocator instance
* @throws BeansException in case of factory loading failure
*/
public static BeanFactoryLocator getInstance() throws BeansException {
return getInstance(null);
}
/**
* Returns an instance which uses the specified selector, as the name of the
* definition file(s). In the case of a name with a Spring "classpath*:" prefix,
* or with no prefix, which is treated the same, the current thread's context class
* loader's {@code getResources} method will be called with this value to get
* all resources having that name. These resources will then be combined to form a
* definition. In the case where the name uses a Spring "classpath:" prefix, or
* a standard URL prefix, then only one resource file will be loaded as the
* definition.
* @param selector the location of the resource(s) which will be read and
* combined to form the definition for the BeanFactoryLocator instance.
* Any such files must form a valid ApplicationContext definition.
* @return the corresponding BeanFactoryLocator instance
* @throws BeansException in case of factory loading failure
*/
public static BeanFactoryLocator getInstance(String selector) throws BeansException {
String resourceLocation = selector;
if (resourceLocation == null) {
resourceLocation = DEFAULT_RESOURCE_LOCATION;
}
// For backwards compatibility, we prepend "classpath*:" to the selector name if there
// is no other prefix (i.e. "classpath*:", "classpath:", or some URL prefix).
if (!ResourcePatternUtils.isUrl(resourceLocation)) {
resourceLocation = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resourceLocation;
}
synchronized (instances) {
if (logger.isTraceEnabled()) {
logger.trace("ContextSingletonBeanFactoryLocator.getInstance(): instances.hashCode=" +
instances.hashCode() + ", instances=" + instances);
}
BeanFactoryLocator bfl = instances.get(resourceLocation);
if (bfl == null) {
bfl = new ContextSingletonBeanFactoryLocator(resourceLocation);
instances.put(resourceLocation, bfl);
}
return bfl;
}
}
/**
* Constructor which uses the specified name as the resource name
* of the definition file(s).
* @param resourceLocation the Spring resource location to use
* (either a URL or a "classpath:" / "classpath*:" pseudo URL)
*/
protected ContextSingletonBeanFactoryLocator(String resourceLocation) {
super(resourceLocation);
}
/**
* Overrides the default method to create definition object as an ApplicationContext
* instead of the default BeanFactory. This does not affect what can actually
* be loaded by that definition.
* <p>The default implementation simply builds a
* {@link org.springframework.context.support.ClassPathXmlApplicationContext}.
*/
@Override
protected BeanFactory createDefinition(String resourceLocation, String factoryKey) {
return new ClassPathXmlApplicationContext(new String[] {resourceLocation}, false);
}
/**
* Overrides the default method to refresh the ApplicationContext, invoking
* {@link ConfigurableApplicationContext#refresh ConfigurableApplicationContext.refresh()}.
*/
@Override
protected void initializeDefinition(BeanFactory groupDef) {
if (groupDef instanceof ConfigurableApplicationContext) {
((ConfigurableApplicationContext) groupDef).refresh();
}
}
/**
* Overrides the default method to operate on an ApplicationContext, invoking
* {@link ConfigurableApplicationContext#refresh ConfigurableApplicationContext.close()}.
*/
@Override
protected void destroyDefinition(BeanFactory groupDef, String selector) {
if (groupDef instanceof ConfigurableApplicationContext) {
if (logger.isTraceEnabled()) {
logger.trace("Context group with selector '" + selector +
"' being released, as there are no more references to it");
}
((ConfigurableApplicationContext) groupDef).close();
}
}
}

View File

@@ -1,49 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.context.access;
import org.springframework.beans.FatalBeanException;
import org.springframework.beans.factory.access.BeanFactoryLocator;
/**
* A factory class to get a default ContextSingletonBeanFactoryLocator instance.
*
* @author Colin Sampaleanu
* @see org.springframework.context.access.ContextSingletonBeanFactoryLocator
*/
public class DefaultLocatorFactory {
/**
* Return an instance object implementing BeanFactoryLocator. This will normally
* be a singleton instance of the specific ContextSingletonBeanFactoryLocator class,
* using the default resource selector.
*/
public static BeanFactoryLocator getInstance() throws FatalBeanException {
return ContextSingletonBeanFactoryLocator.getInstance();
}
/**
* Return an instance object implementing BeanFactoryLocator. This will normally
* be a singleton instance of the specific ContextSingletonBeanFactoryLocator class,
* using the specified resource selector.
* @param selector a selector variable which provides a hint to the factory as to
* which instance to return.
*/
public static BeanFactoryLocator getInstance(String selector) throws FatalBeanException {
return ContextSingletonBeanFactoryLocator.getInstance(selector);
}
}

View File

@@ -1,8 +0,0 @@
/**
* Helper infrastructure to locate and access shared application contexts.
*
* <p><b>Note: This package is only relevant for special sharing of application
* contexts, for example behind EJB facades. It is <i>not</i> used in a typical
* web application or standalone application.</b>
*/
package org.springframework.context.access;

View File

@@ -1,224 +0,0 @@
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ejb.interceptor;
import java.util.Map;
import java.util.WeakHashMap;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.EJBException;
import javax.ejb.PostActivate;
import javax.ejb.PrePassivate;
import javax.interceptor.InvocationContext;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.access.BeanFactoryLocator;
import org.springframework.beans.factory.access.BeanFactoryReference;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.access.ContextSingletonBeanFactoryLocator;
/**
* EJB3-compliant interceptor class that injects Spring beans into
* fields and methods which are annotated with {@code @Autowired}.
* Performs injection after construction as well as after activation
* of a passivated bean.
*
* <p>To be applied through an {@code @Interceptors} annotation in
* the EJB Session Bean or Message-Driven Bean class, or through an
* {@code interceptor-binding} XML element in the EJB deployment descriptor.
*
* <p>Delegates to Spring's {@link AutowiredAnnotationBeanPostProcessor}
* underneath, allowing for customization of its specific settings through
* overriding the {@link #configureBeanPostProcessor} template method.
*
* <p>The actual BeanFactory to obtain Spring beans from is determined
* by the {@link #getBeanFactory} template method. The default implementation
* obtains the Spring {@link ContextSingletonBeanFactoryLocator}, initialized
* from the default resource location <strong>classpath*:beanRefContext.xml</strong>,
* and obtains the single ApplicationContext defined there.
*
* <p><b>NOTE: If you have more than one shared ApplicationContext definition available
* in your EJB class loader, you need to override the {@link #getBeanFactoryLocatorKey}
* method and provide a specific locator key for each autowired EJB.</b>
* Alternatively, override the {@link #getBeanFactory} template method and
* obtain the target factory explicitly.
*
* <p><b>WARNING: Do not define the same bean as Spring-managed bean and as
* EJB3 session bean in the same deployment unit.</b> In particular, be
* careful when using the {@code <context:component-scan>} feature
* in combination with the deployment of Spring-based EJB3 session beans:
* Make sure that the EJB3 session beans are <i>not</i> autodetected as
* Spring-managed beans as well, using appropriate package restrictions.
*
* @author Juergen Hoeller
* @since 2.5.1
* @see org.springframework.beans.factory.annotation.Autowired
* @see org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
* @see org.springframework.context.access.ContextSingletonBeanFactoryLocator
* @see #getBeanFactoryLocatorKey
*/
public class SpringBeanAutowiringInterceptor {
/*
* We're keeping the BeanFactoryReference per target object in order to
* allow for using a shared interceptor instance on pooled target beans.
* This is not strictly necessary for EJB3 Session Beans and Message-Driven
* Beans, where interceptor instances get created per target bean instance.
* It simply protects against future usage of the interceptor in a shared scenario.
*/
private final Map<Object, BeanFactoryReference> beanFactoryReferences =
new WeakHashMap<>();
/**
* Autowire the target bean after construction as well as after passivation.
* @param invocationContext the EJB3 invocation context
*/
@PostConstruct
@PostActivate
public void autowireBean(InvocationContext invocationContext) {
doAutowireBean(invocationContext.getTarget());
try {
invocationContext.proceed();
}
catch (RuntimeException ex) {
doReleaseBean(invocationContext.getTarget());
throw ex;
}
catch (Error err) {
doReleaseBean(invocationContext.getTarget());
throw err;
}
catch (Exception ex) {
doReleaseBean(invocationContext.getTarget());
// Cannot declare a checked exception on WebSphere here - so we need to wrap.
throw new EJBException(ex);
}
}
/**
* Actually autowire the target bean after construction/passivation.
* @param target the target bean to autowire
*/
protected void doAutowireBean(Object target) {
AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
configureBeanPostProcessor(bpp, target);
bpp.setBeanFactory(getBeanFactory(target));
bpp.processInjection(target);
}
/**
* Template method for configuring the
* {@link AutowiredAnnotationBeanPostProcessor} used for autowiring.
* @param processor the AutowiredAnnotationBeanPostProcessor to configure
* @param target the target bean to autowire with this processor
*/
protected void configureBeanPostProcessor(AutowiredAnnotationBeanPostProcessor processor, Object target) {
}
/**
* Determine the BeanFactory for autowiring the given target bean.
* @param target the target bean to autowire
* @return the BeanFactory to use (never {@code null})
* @see #getBeanFactoryReference
*/
protected BeanFactory getBeanFactory(Object target) {
BeanFactory factory = getBeanFactoryReference(target).getFactory();
if (factory instanceof ApplicationContext) {
factory = ((ApplicationContext) factory).getAutowireCapableBeanFactory();
}
return factory;
}
/**
* Determine the BeanFactoryReference for the given target bean.
* <p>The default implementation delegates to {@link #getBeanFactoryLocator}
* and {@link #getBeanFactoryLocatorKey}.
* @param target the target bean to autowire
* @return the BeanFactoryReference to use (never {@code null})
* @see #getBeanFactoryLocator
* @see #getBeanFactoryLocatorKey
* @see org.springframework.beans.factory.access.BeanFactoryLocator#useBeanFactory(String)
*/
protected BeanFactoryReference getBeanFactoryReference(Object target) {
String key = getBeanFactoryLocatorKey(target);
BeanFactoryReference ref = getBeanFactoryLocator(target).useBeanFactory(key);
this.beanFactoryReferences.put(target, ref);
return ref;
}
/**
* Determine the BeanFactoryLocator to obtain the BeanFactoryReference from.
* <p>The default implementation exposes Spring's default
* {@link ContextSingletonBeanFactoryLocator}.
* @param target the target bean to autowire
* @return the BeanFactoryLocator to use (never {@code null})
* @see org.springframework.context.access.ContextSingletonBeanFactoryLocator#getInstance()
*/
protected BeanFactoryLocator getBeanFactoryLocator(Object target) {
return ContextSingletonBeanFactoryLocator.getInstance();
}
/**
* Determine the BeanFactoryLocator key to use. This typically indicates
* the bean name of the ApplicationContext definition in
* <strong>classpath*:beanRefContext.xml</strong> resource files.
* <p>The default is {@code null}, indicating the single
* ApplicationContext defined in the locator. This must be overridden
* if more than one shared ApplicationContext definition is available.
* @param target the target bean to autowire
* @return the BeanFactoryLocator key to use (or {@code null} for
* referring to the single ApplicationContext defined in the locator)
*/
protected String getBeanFactoryLocatorKey(Object target) {
return null;
}
/**
* Release the factory which has been used for autowiring the target bean.
* @param invocationContext the EJB3 invocation context
*/
@PreDestroy
@PrePassivate
public void releaseBean(InvocationContext invocationContext) {
doReleaseBean(invocationContext.getTarget());
try {
invocationContext.proceed();
}
catch (RuntimeException ex) {
throw ex;
}
catch (Exception ex) {
// Cannot declare a checked exception on WebSphere here - so we need to wrap.
throw new EJBException(ex);
}
}
/**
* Actually release the BeanFactoryReference for the given target bean.
* @param target the target bean to release
*/
protected void doReleaseBean(Object target) {
BeanFactoryReference ref = this.beanFactoryReferences.remove(target);
if (ref != null) {
ref.release();
}
}
}

View File

@@ -1,6 +0,0 @@
/**
* Support classes for EJB 3 Session Beans and Message-Driven Beans,
* performing injection of Spring beans through an EJB 3 interceptor
* that processes Spring's {@code @Autowired} annotation.
*/
package org.springframework.ejb.interceptor;

View File

@@ -1,52 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.context.access;
import org.junit.Test;
import org.springframework.context.ConfigurableApplicationContext;
import static org.junit.Assert.*;
import static org.mockito.BDDMockito.*;
/**
* Unit test for {@link ContextBeanFactoryReference}
*
* @author Colin Sampaleanu
* @author Chris Beams
*/
public class ContextBeanFactoryReferenceTests {
@Test
public void testAllOperations() {
ConfigurableApplicationContext ctx = mock(ConfigurableApplicationContext.class);
ContextBeanFactoryReference bfr = new ContextBeanFactoryReference(ctx);
assertNotNull(bfr.getFactory());
bfr.release();
try {
bfr.getFactory();
}
catch (IllegalStateException e) {
// expected
}
verify(ctx).close();
}
}

View File

@@ -1,173 +0,0 @@
/*
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.context.access;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import org.junit.Test;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.access.BootstrapException;
import org.springframework.context.ApplicationContext;
import org.springframework.tests.mock.jndi.SimpleNamingContextBuilder;
import static org.junit.Assert.*;
/**
* @author Colin Sampaleanu
* @author Chris Beams
*/
public class ContextJndiBeanFactoryLocatorTests {
private static final String BEAN_FACTORY_PATH_ENVIRONMENT_KEY = "java:comp/env/ejb/BeanFactoryPath";
private static final Class<?> CLASS = ContextJndiBeanFactoryLocatorTests.class;
private static final String CLASSNAME = CLASS.getSimpleName();
private static final String FQ_PATH = "/org/springframework/context/access/";
private static final String COLLECTIONS_CONTEXT = FQ_PATH + CLASSNAME + "-collections.xml";
private static final String PARENT_CONTEXT = FQ_PATH + CLASSNAME + "-parent.xml";
@Test
public void beanFactoryPathRequiredFromJndiEnvironment() throws Exception {
// Set up initial context but don't bind anything
SimpleNamingContextBuilder.emptyActivatedContextBuilder();
ContextJndiBeanFactoryLocator jbfl = new ContextJndiBeanFactoryLocator();
try {
jbfl.useBeanFactory(BEAN_FACTORY_PATH_ENVIRONMENT_KEY);
fail();
}
catch (BootstrapException ex) {
// Check for helpful JNDI message
assertTrue(ex.getMessage().indexOf(BEAN_FACTORY_PATH_ENVIRONMENT_KEY) != -1);
}
}
@Test
public void beanFactoryPathFromJndiEnvironmentNotFound() throws Exception {
SimpleNamingContextBuilder sncb = SimpleNamingContextBuilder.emptyActivatedContextBuilder();
String bogusPath = "RUBBISH/com/xxxx/framework/server/test1.xml";
// Set up initial context
sncb.bind(BEAN_FACTORY_PATH_ENVIRONMENT_KEY, bogusPath);
ContextJndiBeanFactoryLocator jbfl = new ContextJndiBeanFactoryLocator();
try {
jbfl.useBeanFactory(BEAN_FACTORY_PATH_ENVIRONMENT_KEY);
fail();
}
catch (BeansException ex) {
// Check for helpful JNDI message
assertTrue(ex.getMessage().indexOf(bogusPath) != -1);
}
}
@Test
public void beanFactoryPathFromJndiEnvironmentNotValidXml() throws Exception {
SimpleNamingContextBuilder sncb = SimpleNamingContextBuilder.emptyActivatedContextBuilder();
String nonXmlPath = "com/xxxx/framework/server/SlsbEndpointBean.class";
// Set up initial context
sncb.bind(BEAN_FACTORY_PATH_ENVIRONMENT_KEY, nonXmlPath);
ContextJndiBeanFactoryLocator jbfl = new ContextJndiBeanFactoryLocator();
try {
jbfl.useBeanFactory(BEAN_FACTORY_PATH_ENVIRONMENT_KEY);
fail();
}
catch (BeansException ex) {
// Check for helpful JNDI message
assertTrue(ex.getMessage().indexOf(nonXmlPath) != -1);
}
}
@Test
public void beanFactoryPathFromJndiEnvironmentWithSingleFile() throws Exception {
SimpleNamingContextBuilder sncb = SimpleNamingContextBuilder.emptyActivatedContextBuilder();
// Set up initial context
sncb.bind(BEAN_FACTORY_PATH_ENVIRONMENT_KEY, COLLECTIONS_CONTEXT);
ContextJndiBeanFactoryLocator jbfl = new ContextJndiBeanFactoryLocator();
BeanFactory bf = jbfl.useBeanFactory(BEAN_FACTORY_PATH_ENVIRONMENT_KEY).getFactory();
assertTrue(bf.containsBean("rod"));
assertTrue(bf instanceof ApplicationContext);
}
@Test
public void beanFactoryPathFromJndiEnvironmentWithMultipleFiles() throws Exception {
SimpleNamingContextBuilder sncb = SimpleNamingContextBuilder.emptyActivatedContextBuilder();
String path = String.format("%s %s", COLLECTIONS_CONTEXT, PARENT_CONTEXT);
// Set up initial context
sncb.bind(BEAN_FACTORY_PATH_ENVIRONMENT_KEY, path);
ContextJndiBeanFactoryLocator jbfl = new ContextJndiBeanFactoryLocator();
BeanFactory bf = jbfl.useBeanFactory(BEAN_FACTORY_PATH_ENVIRONMENT_KEY).getFactory();
assertTrue(bf.containsBean("rod"));
assertTrue(bf.containsBean("inheritedTestBean"));
}
}
class MapAndSet {
private Object obj;
public MapAndSet(Map<?, ?> map) {
this.obj = map;
}
public MapAndSet(Set<?> set) {
this.obj = set;
}
public Object getObject() {
return obj;
}
}
/**
* Bean that exposes a simple property that can be set
* to a mix of references and individual values.
*/
class MixedCollectionBean {
private Collection<?> jumble;
public void setJumble(Collection<?> jumble) {
this.jumble = jumble;
}
public Collection<?> getJumble() {
return jumble;
}
}

View File

@@ -1,97 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.context.access;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.access.BeanFactoryLocator;
import org.springframework.beans.factory.access.BeanFactoryReference;
import org.springframework.beans.factory.access.SingletonBeanFactoryLocatorTests;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.ClassUtils;
import static org.junit.Assert.*;
/**
* @author Colin Sampaleanu
* @author Juergen Hoeller
* @author Chris Beams
*/
public class ContextSingletonBeanFactoryLocatorTests extends SingletonBeanFactoryLocatorTests {
private static final Class<?> CLASS = ContextSingletonBeanFactoryLocatorTests.class;
private static final String CONTEXT = CLASS.getSimpleName() + "-context.xml";
@Test
public void testBaseBeanFactoryDefs() {
// Just test the base BeanFactory/AppContext defs we are going to work
// with in other tests.
new XmlBeanDefinitionReader(new DefaultListableBeanFactory()).loadBeanDefinitions(new ClassPathResource(
"/org/springframework/beans/factory/access/beans1.xml"));
new XmlBeanDefinitionReader(new DefaultListableBeanFactory()).loadBeanDefinitions(new ClassPathResource(
"/org/springframework/beans/factory/access/beans2.xml"));
}
@Override
@Test
public void testBasicFunctionality() {
ContextSingletonBeanFactoryLocator facLoc = new ContextSingletonBeanFactoryLocator(
"classpath*:" + ClassUtils.addResourcePathToPackagePath(CLASS, CONTEXT));
basicFunctionalityTest(facLoc);
BeanFactoryReference bfr = facLoc.useBeanFactory("a.qualified.name.of.some.sort");
BeanFactory fac = bfr.getFactory();
assertTrue(fac instanceof ApplicationContext);
assertEquals("a.qualified.name.of.some.sort", ((ApplicationContext) fac).getId());
assertTrue(((ApplicationContext) fac).getDisplayName().contains("a.qualified.name.of.some.sort"));
BeanFactoryReference bfr2 = facLoc.useBeanFactory("another.qualified.name");
BeanFactory fac2 = bfr2.getFactory();
assertEquals("another.qualified.name", ((ApplicationContext) fac2).getId());
assertTrue(((ApplicationContext) fac2).getDisplayName().contains("another.qualified.name"));
assertTrue(fac2 instanceof ApplicationContext);
}
/**
* This test can run multiple times, but due to static keyed lookup of the locators,
* 2nd and subsequent calls will actually get back same locator instance. This is not
* really an issue, since the contained bean factories will still be loaded and released.
*/
@Override
@Test
public void testGetInstance() {
// Try with and without 'classpath*:' prefix, and with 'classpath:' prefix.
BeanFactoryLocator facLoc = ContextSingletonBeanFactoryLocator.getInstance(
ClassUtils.addResourcePathToPackagePath(CLASS, CONTEXT));
getInstanceTest1(facLoc);
facLoc = ContextSingletonBeanFactoryLocator.getInstance(
"classpath*:" + ClassUtils.addResourcePathToPackagePath(CLASS, CONTEXT));
getInstanceTest2(facLoc);
// This will actually get another locator instance, as the key is the resource name.
facLoc = ContextSingletonBeanFactoryLocator.getInstance(
"classpath:" + ClassUtils.addResourcePathToPackagePath(CLASS, CONTEXT));
getInstanceTest3(facLoc);
}
}

View File

@@ -1,49 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.context.access;
import org.junit.Test;
import static org.junit.Assert.*;
import org.springframework.beans.factory.access.BeanFactoryLocator;
/**
* @author Colin Sampaleanu
*/
public class DefaultLocatorFactoryTests {
/*
* Class to test for BeanFactoryLocator getInstance()
*/
@Test
public void getInstance() {
BeanFactoryLocator bf = DefaultLocatorFactory.getInstance();
BeanFactoryLocator bf2 = DefaultLocatorFactory.getInstance();
assertTrue(bf.equals(bf2));
}
/*
* Class to test for BeanFactoryLocator getInstance(String)
*/
@Test
public void getInstanceString() {
BeanFactoryLocator bf = DefaultLocatorFactory.getInstance("my-bean-refs.xml");
BeanFactoryLocator bf2 = DefaultLocatorFactory.getInstance("my-bean-refs.xml");
assertTrue(bf.equals(bf2));
}
}