Drop outdated BeanFactoryLocator / beanRefContext.xml mechanism
Issue: SPR-15154
This commit is contained in:
parent
d96738d613
commit
ac6aa53031
|
|
@ -439,7 +439,6 @@ project("spring-beans") {
|
|||
compile(project(":spring-core"))
|
||||
compile(files(project(":spring-core").cglibRepackJar))
|
||||
optional("javax.inject:javax.inject:1")
|
||||
optional("javax.el:javax.el-api:${elApiVersion}")
|
||||
optional("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}")
|
||||
optional("org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}")
|
||||
optional("org.yaml:snakeyaml:${snakeyamlVersion}")
|
||||
|
|
@ -722,7 +721,6 @@ project("spring-context-indexer") {
|
|||
project("spring-web") {
|
||||
description = "Spring Web"
|
||||
|
||||
|
||||
apply plugin: "groovy"
|
||||
|
||||
dependencies {
|
||||
|
|
|
|||
|
|
@ -1,68 +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.beans.factory.access;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
|
||||
/**
|
||||
* Defines a contract for the lookup, use, and release of a
|
||||
* {@link org.springframework.beans.factory.BeanFactory},
|
||||
* or a {@code BeanFactory} subclass such as an
|
||||
* {@link org.springframework.context.ApplicationContext}.
|
||||
*
|
||||
* <p>Where this interface is implemented as a singleton class such as
|
||||
* {@link SingletonBeanFactoryLocator}, the Spring team <strong>strongly</strong>
|
||||
* suggests that it be used sparingly and with caution. By far the vast majority
|
||||
* of the code inside an application is best written in a Dependency Injection
|
||||
* style, where that code is served out of a
|
||||
* {@code BeanFactory}/{@code ApplicationContext} container, and has
|
||||
* its own dependencies supplied by the container when it is created. However,
|
||||
* even such a singleton implementation sometimes has its use in the small glue
|
||||
* layers of code that is sometimes needed to tie other code together. For
|
||||
* example, third party code may try to construct new objects directly, without
|
||||
* the ability to force it to get these objects out of a {@code BeanFactory}.
|
||||
* If the object constructed by the third party code is just a small stub or
|
||||
* proxy, which then uses an implementation of this class to get a
|
||||
* {@code BeanFactory} from which it gets the real object, to which it
|
||||
* delegates, then proper Dependency Injection has been achieved.
|
||||
*
|
||||
* <p>As another example, in a complex Java EE app with multiple layers, with
|
||||
* each layer having its own {@code ApplicationContext} definition (in a
|
||||
* hierarchy), a class like {@code SingletonBeanFactoryLocator} may be used
|
||||
* to demand load these contexts.
|
||||
*
|
||||
* @author Colin Sampaleanu
|
||||
* @see org.springframework.beans.factory.BeanFactory
|
||||
* @see org.springframework.context.access.DefaultLocatorFactory
|
||||
* @see org.springframework.context.ApplicationContext
|
||||
*/
|
||||
public interface BeanFactoryLocator {
|
||||
|
||||
/**
|
||||
* Use the {@link org.springframework.beans.factory.BeanFactory} (or derived
|
||||
* interface such as {@link org.springframework.context.ApplicationContext})
|
||||
* specified by the {@code factoryKey} parameter.
|
||||
* <p>The definition is possibly loaded/created as needed.
|
||||
* @param factoryKey a resource name specifying which {@code BeanFactory} the
|
||||
* {@code BeanFactoryLocator} must return for usage. The actual meaning of the
|
||||
* resource name is specific to the implementation of {@code BeanFactoryLocator}.
|
||||
* @return the {@code BeanFactory} instance, wrapped as a {@link BeanFactoryReference} object
|
||||
* @throws BeansException if there is an error loading or accessing the {@code BeanFactory}
|
||||
*/
|
||||
BeanFactoryReference useBeanFactory(String factoryKey) throws BeansException;
|
||||
|
||||
}
|
||||
|
|
@ -1,57 +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.beans.factory.access;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
|
||||
/**
|
||||
* Used to track a reference to a {@link BeanFactory} obtained through
|
||||
* a {@link BeanFactoryLocator}.
|
||||
*
|
||||
* <p>It is safe to call {@link #release()} multiple times, but
|
||||
* {@link #getFactory()} must not be called after calling release.
|
||||
*
|
||||
* @author Colin Sampaleanu
|
||||
* @see BeanFactoryLocator
|
||||
* @see org.springframework.context.access.ContextBeanFactoryReference
|
||||
*/
|
||||
public interface BeanFactoryReference {
|
||||
|
||||
/**
|
||||
* Return the {@link BeanFactory} instance held by this reference.
|
||||
* @throws IllegalStateException if invoked after {@code release()} has been called
|
||||
*/
|
||||
BeanFactory getFactory();
|
||||
|
||||
/**
|
||||
* Indicate that the {@link BeanFactory} instance referred to by this object is not
|
||||
* needed any longer by the client code which obtained the {@link BeanFactoryReference}.
|
||||
* <p>Depending on the actual implementation of {@link BeanFactoryLocator}, and
|
||||
* the actual type of {@code BeanFactory}, this may possibly not actually
|
||||
* do anything; alternately in the case of a 'closeable' {@code BeanFactory}
|
||||
* or derived class (such as {@link org.springframework.context.ApplicationContext})
|
||||
* may 'close' it, or may 'close' it once no more references remain.
|
||||
* <p>In an EJB usage scenario this would normally be called from
|
||||
* {@code ejbRemove()} and {@code ejbPassivate()}.
|
||||
* <p>This is safe to call multiple times.
|
||||
* @see BeanFactoryLocator
|
||||
* @see org.springframework.context.access.ContextBeanFactoryReference
|
||||
* @see org.springframework.context.ConfigurableApplicationContext#close()
|
||||
*/
|
||||
void release();
|
||||
|
||||
}
|
||||
|
|
@ -1,48 +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.beans.factory.access;
|
||||
|
||||
import org.springframework.beans.FatalBeanException;
|
||||
|
||||
/**
|
||||
* Exception thrown if a bean factory could not be loaded by a bootstrap class.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @since 02.12.2002
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class BootstrapException extends FatalBeanException {
|
||||
|
||||
/**
|
||||
* Create a new BootstrapException with the specified message.
|
||||
* @param msg the detail message
|
||||
*/
|
||||
public BootstrapException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new BootstrapException with the specified message
|
||||
* and root cause.
|
||||
* @param msg the detail message
|
||||
* @param cause the root cause
|
||||
*/
|
||||
public BootstrapException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,536 +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.beans.factory.access;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.FatalBeanException;
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
import org.springframework.core.io.support.ResourcePatternUtils;
|
||||
|
||||
/**
|
||||
* <p>Keyed-singleton implementation of {@link BeanFactoryLocator},
|
||||
* which accesses shared Spring {@link BeanFactory} instances.</p>
|
||||
*
|
||||
* <p>Please see the warning in BeanFactoryLocator's javadoc about appropriate usage
|
||||
* of singleton style BeanFactoryLocator implementations. It is the opinion of the
|
||||
* Spring team that the use of this class and similar classes is unnecessary except
|
||||
* (sometimes) for a small amount of glue code. Excessive usage will lead to code
|
||||
* that is more tightly coupled, and harder to modify or test.</p>
|
||||
*
|
||||
* <p>In this implementation, a BeanFactory is built up from one or more XML
|
||||
* definition file fragments, accessed as resources. The default resource name
|
||||
* searched for is 'classpath*:beanRefFactory.xml', with the Spring-standard
|
||||
* 'classpath*:' prefix ensuring that if the classpath contains multiple copies
|
||||
* of this file (perhaps one in each component jar) they will be combined. To
|
||||
* override the default resource name, instead of using the no-arg
|
||||
* {@link #getInstance()} method, use the {@link #getInstance(String selector)}
|
||||
* variant, which will treat the 'selector' argument as the resource name to
|
||||
* search for.</p>
|
||||
*
|
||||
* <p>The purpose of this 'outer' BeanFactory is to create and hold a copy of one
|
||||
* or more 'inner' BeanFactory or ApplicationContext instances, and allow those
|
||||
* to be obtained either directly or via an alias. As such, this class provides
|
||||
* both singleton style access to one or more BeanFactories/ApplicationContexts,
|
||||
* and also a level of indirection, allowing multiple pieces of code, which are
|
||||
* not able to work in a Dependency Injection fashion, to refer to and use the
|
||||
* same target BeanFactory/ApplicationContext instance(s), by different names.<p>
|
||||
*
|
||||
* <p>Consider an example application scenario:
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@code com.mycompany.myapp.util.applicationContext.xml} -
|
||||
* ApplicationContext definition file which defines beans for 'util' layer.
|
||||
* <li>{@code com.mycompany.myapp.dataaccess-applicationContext.xml} -
|
||||
* ApplicationContext definition file which defines beans for 'data access' layer.
|
||||
* Depends on the above.
|
||||
* <li>{@code com.mycompany.myapp.services.applicationContext.xml} -
|
||||
* ApplicationContext definition file which defines beans for 'services' layer.
|
||||
* Depends on the above.
|
||||
* </ul>
|
||||
*
|
||||
* <p>In an ideal scenario, these would be combined to create one ApplicationContext,
|
||||
* or created as three hierarchical ApplicationContexts, by one piece of code
|
||||
* somewhere at application startup (perhaps a Servlet filter), from which all other
|
||||
* code in the application would flow, obtained as beans from the context(s). However
|
||||
* when third party code enters into the picture, things can get problematic. If the
|
||||
* third party code needs to create user classes, which should normally be obtained
|
||||
* from a Spring BeanFactory/ApplicationContext, but can handle only newInstance()
|
||||
* style object creation, then some extra work is required to actually access and
|
||||
* use object from a BeanFactory/ApplicationContext. One solutions is to make the
|
||||
* class created by the third party code be just a stub or proxy, which gets the
|
||||
* real object from a BeanFactory/ApplicationContext, and delegates to it. However,
|
||||
* it is not normally workable for the stub to create the BeanFactory on each
|
||||
* use, as depending on what is inside it, that can be an expensive operation.
|
||||
* Additionally, there is a fairly tight coupling between the stub and the name of
|
||||
* the definition resource for the BeanFactory/ApplicationContext. This is where
|
||||
* SingletonBeanFactoryLocator comes in. The stub can obtain a
|
||||
* SingletonBeanFactoryLocator instance, which is effectively a singleton, and
|
||||
* ask it for an appropriate BeanFactory. A subsequent invocation (assuming the
|
||||
* same class loader is involved) by the stub or another piece of code, will obtain
|
||||
* the same instance. The simple aliasing mechanism allows the context to be asked
|
||||
* for by a name which is appropriate for (or describes) the user. The deployer can
|
||||
* match alias names to actual context names.
|
||||
*
|
||||
* <p>Another use of SingletonBeanFactoryLocator, is to demand-load/use one or more
|
||||
* BeanFactories/ApplicationContexts. Because the definition can contain one of more
|
||||
* BeanFactories/ApplicationContexts, which can be independent or in a hierarchy, if
|
||||
* they are set to lazy-initialize, they will only be created when actually requested
|
||||
* for use.
|
||||
*
|
||||
* <p>Given the above-mentioned three ApplicationContexts, consider the simplest
|
||||
* SingletonBeanFactoryLocator usage scenario, where there is only one single
|
||||
* {@code beanRefFactory.xml} definition file:
|
||||
*
|
||||
* <pre class="code"><?xml version="1.0" encoding="UTF-8"?>
|
||||
* <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||
*
|
||||
* <beans>
|
||||
*
|
||||
* <bean id="com.mycompany.myapp"
|
||||
* class="org.springframework.context.support.ClassPathXmlApplicationContext">
|
||||
* <constructor-arg>
|
||||
* <list>
|
||||
* <value>com/mycompany/myapp/util/applicationContext.xml</value>
|
||||
* <value>com/mycompany/myapp/dataaccess/applicationContext.xml</value>
|
||||
* <value>com/mycompany/myapp/dataaccess/services.xml</value>
|
||||
* </list>
|
||||
* </constructor-arg>
|
||||
* </bean>
|
||||
*
|
||||
* </beans>
|
||||
* </pre>
|
||||
*
|
||||
* The client code is as simple as:
|
||||
*
|
||||
* <pre class="code">
|
||||
* BeanFactoryLocator bfl = SingletonBeanFactoryLocator.getInstance();
|
||||
* BeanFactoryReference bf = bfl.useBeanFactory("com.mycompany.myapp");
|
||||
* // now use some bean from factory
|
||||
* MyClass zed = bf.getFactory().getBean("mybean");
|
||||
* </pre>
|
||||
*
|
||||
* Another relatively simple variation of the {@code beanRefFactory.xml} definition file could be:
|
||||
*
|
||||
* <pre class="code"><?xml version="1.0" encoding="UTF-8"?>
|
||||
* <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||
*
|
||||
* <beans>
|
||||
*
|
||||
* <bean id="com.mycompany.myapp.util" lazy-init="true"
|
||||
* class="org.springframework.context.support.ClassPathXmlApplicationContext">
|
||||
* <constructor-arg>
|
||||
* <value>com/mycompany/myapp/util/applicationContext.xml</value>
|
||||
* </constructor-arg>
|
||||
* </bean>
|
||||
*
|
||||
* <!-- child of above -->
|
||||
* <bean id="com.mycompany.myapp.dataaccess" lazy-init="true"
|
||||
* class="org.springframework.context.support.ClassPathXmlApplicationContext">
|
||||
* <constructor-arg>
|
||||
* <list><value>com/mycompany/myapp/dataaccess/applicationContext.xml</value></list>
|
||||
* </constructor-arg>
|
||||
* <constructor-arg>
|
||||
* <ref bean="com.mycompany.myapp.util"/>
|
||||
* </constructor-arg>
|
||||
* </bean>
|
||||
*
|
||||
* <!-- child of above -->
|
||||
* <bean id="com.mycompany.myapp.services" lazy-init="true"
|
||||
* class="org.springframework.context.support.ClassPathXmlApplicationContext">
|
||||
* <constructor-arg>
|
||||
* <list><value>com/mycompany/myapp/dataaccess.services.xml</value></value>
|
||||
* </constructor-arg>
|
||||
* <constructor-arg>
|
||||
* <ref bean="com.mycompany.myapp.dataaccess"/>
|
||||
* </constructor-arg>
|
||||
* </bean>
|
||||
*
|
||||
* <!-- define an alias -->
|
||||
* <bean id="com.mycompany.myapp.mypackage"
|
||||
* class="java.lang.String">
|
||||
* <constructor-arg>
|
||||
* <value>com.mycompany.myapp.services</value>
|
||||
* </constructor-arg>
|
||||
* </bean>
|
||||
*
|
||||
* </beans>
|
||||
* </pre>
|
||||
*
|
||||
* <p>In this example, there is a hierarchy of three contexts created. The (potential)
|
||||
* advantage is that if the lazy flag is set to true, a context will only be created
|
||||
* if it's actually used. If there is some code that is only needed some of the time,
|
||||
* this mechanism can save some resources. Additionally, an alias to the last context
|
||||
* has been created. Aliases allow usage of the idiom where client code asks for a
|
||||
* context with an id which represents the package or module the code is in, and the
|
||||
* actual definition file(s) for the SingletonBeanFactoryLocator maps that id to
|
||||
* a real context id.
|
||||
*
|
||||
* <p>A final example is more complex, with a {@code beanRefFactory.xml} for every module.
|
||||
* All the files are automatically combined to create the final definition.
|
||||
*
|
||||
* <p>{@code beanRefFactory.xml} file inside jar for util module:
|
||||
*
|
||||
* <pre class="code"><?xml version="1.0" encoding="UTF-8"?>
|
||||
* <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||
*
|
||||
* <beans>
|
||||
* <bean id="com.mycompany.myapp.util" lazy-init="true"
|
||||
* class="org.springframework.context.support.ClassPathXmlApplicationContext">
|
||||
* <constructor-arg>
|
||||
* <value>com/mycompany/myapp/util/applicationContext.xml</value>
|
||||
* </constructor-arg>
|
||||
* </bean>
|
||||
* </beans>
|
||||
* </pre>
|
||||
*
|
||||
* {@code beanRefFactory.xml} file inside jar for data-access module:<br>
|
||||
*
|
||||
* <pre class="code"><?xml version="1.0" encoding="UTF-8"?>
|
||||
* <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||
*
|
||||
* <beans>
|
||||
* <!-- child of util -->
|
||||
* <bean id="com.mycompany.myapp.dataaccess" lazy-init="true"
|
||||
* class="org.springframework.context.support.ClassPathXmlApplicationContext">
|
||||
* <constructor-arg>
|
||||
* <list><value>com/mycompany/myapp/dataaccess/applicationContext.xml</value></list>
|
||||
* </constructor-arg>
|
||||
* <constructor-arg>
|
||||
* <ref bean="com.mycompany.myapp.util"/>
|
||||
* </constructor-arg>
|
||||
* </bean>
|
||||
* </beans>
|
||||
* </pre>
|
||||
*
|
||||
* {@code beanRefFactory.xml} file inside jar for services module:
|
||||
*
|
||||
* <pre class="code"><?xml version="1.0" encoding="UTF-8"?>
|
||||
* <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||
*
|
||||
* <beans>
|
||||
* <!-- child of data-access -->
|
||||
* <bean id="com.mycompany.myapp.services" lazy-init="true"
|
||||
* class="org.springframework.context.support.ClassPathXmlApplicationContext">
|
||||
* <constructor-arg>
|
||||
* <list><value>com/mycompany/myapp/dataaccess/services.xml</value></list>
|
||||
* </constructor-arg>
|
||||
* <constructor-arg>
|
||||
* <ref bean="com.mycompany.myapp.dataaccess"/>
|
||||
* </constructor-arg>
|
||||
* </bean>
|
||||
* </beans>
|
||||
* </pre>
|
||||
*
|
||||
* {@code beanRefFactory.xml} file inside jar for mypackage module. This doesn't
|
||||
* create any of its own contexts, but allows the other ones to be referred to be
|
||||
* a name known to this module:
|
||||
*
|
||||
* <pre class="code"><?xml version="1.0" encoding="UTF-8"?>
|
||||
* <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||
*
|
||||
* <beans>
|
||||
* <!-- define an alias for "com.mycompany.myapp.services" -->
|
||||
* <alias name="com.mycompany.myapp.services" alias="com.mycompany.myapp.mypackage"/>
|
||||
* </beans>
|
||||
* </pre>
|
||||
*
|
||||
* @author Colin Sampaleanu
|
||||
* @author Juergen Hoeller
|
||||
* @see org.springframework.context.access.ContextSingletonBeanFactoryLocator
|
||||
* @see org.springframework.context.access.DefaultLocatorFactory
|
||||
*/
|
||||
public class SingletonBeanFactoryLocator implements BeanFactoryLocator {
|
||||
|
||||
private static final String DEFAULT_RESOURCE_LOCATION = "classpath*:beanRefFactory.xml";
|
||||
|
||||
protected static final Log logger = LogFactory.getLog(SingletonBeanFactoryLocator.class);
|
||||
|
||||
/** The keyed BeanFactory instances */
|
||||
private static final Map<String, BeanFactoryLocator> instances = new HashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* Returns an instance which uses the default "classpath*:beanRefFactory.xml",
|
||||
* as the name of the definition file(s). All resources returned by calling the
|
||||
* current thread context ClassLoader's {@code getResources} method with
|
||||
* this name will be combined to create a BeanFactory definition set.
|
||||
* @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 context
|
||||
* ClassLoader'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 name 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 BeanFactory 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("SingletonBeanFactoryLocator.getInstance(): instances.hashCode=" +
|
||||
instances.hashCode() + ", instances=" + instances);
|
||||
}
|
||||
BeanFactoryLocator bfl = instances.get(resourceLocation);
|
||||
if (bfl == null) {
|
||||
bfl = new SingletonBeanFactoryLocator(resourceLocation);
|
||||
instances.put(resourceLocation, bfl);
|
||||
}
|
||||
return bfl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// We map BeanFactoryGroup objects by String keys, and by the definition object.
|
||||
private final Map<String, BeanFactoryGroup> bfgInstancesByKey = new HashMap<>();
|
||||
|
||||
private final Map<BeanFactory, BeanFactoryGroup> bfgInstancesByObj = new HashMap<>();
|
||||
|
||||
private final String resourceLocation;
|
||||
|
||||
|
||||
/**
|
||||
* 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 SingletonBeanFactoryLocator(String resourceLocation) {
|
||||
this.resourceLocation = resourceLocation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanFactoryReference useBeanFactory(String factoryKey) throws BeansException {
|
||||
synchronized (this.bfgInstancesByKey) {
|
||||
BeanFactoryGroup bfg = this.bfgInstancesByKey.get(this.resourceLocation);
|
||||
|
||||
if (bfg != null) {
|
||||
bfg.refCount++;
|
||||
}
|
||||
else {
|
||||
// This group definition doesn't exist, we need to try to load it.
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Factory group with resource name [" + this.resourceLocation +
|
||||
"] requested. Creating new instance.");
|
||||
}
|
||||
|
||||
// Create the BeanFactory but don't initialize it.
|
||||
BeanFactory groupContext = createDefinition(this.resourceLocation, factoryKey);
|
||||
|
||||
// Record its existence now, before instantiating any singletons.
|
||||
bfg = new BeanFactoryGroup();
|
||||
bfg.definition = groupContext;
|
||||
bfg.refCount = 1;
|
||||
this.bfgInstancesByKey.put(this.resourceLocation, bfg);
|
||||
this.bfgInstancesByObj.put(groupContext, bfg);
|
||||
|
||||
// Now initialize the BeanFactory. This may cause a re-entrant invocation
|
||||
// of this method, but since we've already added the BeanFactory to our
|
||||
// mappings, the next time it will be found and simply have its
|
||||
// reference count incremented.
|
||||
try {
|
||||
initializeDefinition(groupContext);
|
||||
}
|
||||
catch (BeansException ex) {
|
||||
this.bfgInstancesByKey.remove(this.resourceLocation);
|
||||
this.bfgInstancesByObj.remove(groupContext);
|
||||
throw new BootstrapException("Unable to initialize group definition. " +
|
||||
"Group resource name [" + this.resourceLocation + "], factory key [" + factoryKey + "]", ex);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
BeanFactory beanFactory;
|
||||
if (factoryKey != null) {
|
||||
beanFactory = bfg.definition.getBean(factoryKey, BeanFactory.class);
|
||||
}
|
||||
else {
|
||||
beanFactory = bfg.definition.getBean(BeanFactory.class);
|
||||
}
|
||||
return new CountingBeanFactoryReference(beanFactory, bfg.definition);
|
||||
}
|
||||
catch (BeansException ex) {
|
||||
throw new BootstrapException("Unable to return specified BeanFactory instance: factory key [" +
|
||||
factoryKey + "], from group with resource name [" + this.resourceLocation + "]", ex);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually creates definition in the form of a BeanFactory, given a resource name
|
||||
* which supports standard Spring resource prefixes ('classpath:', 'classpath*:', etc.)
|
||||
* This is split out as a separate method so that subclasses can override the actual
|
||||
* type used (to be an ApplicationContext, for example).
|
||||
* <p>The default implementation simply builds a
|
||||
* {@link org.springframework.beans.factory.support.DefaultListableBeanFactory}
|
||||
* and populates it using an
|
||||
* {@link org.springframework.beans.factory.xml.XmlBeanDefinitionReader}.
|
||||
* <p>This method should not instantiate any singletons. That function is performed
|
||||
* by {@link #initializeDefinition initializeDefinition()}, which should also be
|
||||
* overridden if this method is.
|
||||
* @param resourceLocation the resource location for this factory group
|
||||
* @param factoryKey the bean name of the factory to obtain
|
||||
* @return the corresponding BeanFactory reference
|
||||
*/
|
||||
protected BeanFactory createDefinition(String resourceLocation, String factoryKey) {
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
|
||||
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
|
||||
|
||||
try {
|
||||
Resource[] configResources = resourcePatternResolver.getResources(resourceLocation);
|
||||
if (configResources.length == 0) {
|
||||
throw new FatalBeanException("Unable to find resource for specified definition. " +
|
||||
"Group resource name [" + this.resourceLocation + "], factory key [" + factoryKey + "]");
|
||||
}
|
||||
reader.loadBeanDefinitions(configResources);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new BeanDefinitionStoreException(
|
||||
"Error accessing bean definition resource [" + this.resourceLocation + "]", ex);
|
||||
}
|
||||
catch (BeanDefinitionStoreException ex) {
|
||||
throw new FatalBeanException("Unable to load group definition: " +
|
||||
"group resource name [" + this.resourceLocation + "], factory key [" + factoryKey + "]", ex);
|
||||
}
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate singletons and do any other normal initialization of the factory.
|
||||
* Subclasses that override {@link #createDefinition createDefinition()} should
|
||||
* also override this method.
|
||||
* @param groupDef the factory returned by {@link #createDefinition createDefinition()}
|
||||
*/
|
||||
protected void initializeDefinition(BeanFactory groupDef) {
|
||||
if (groupDef instanceof ConfigurableListableBeanFactory) {
|
||||
((ConfigurableListableBeanFactory) groupDef).preInstantiateSingletons();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy definition in separate method so subclass may work with other definition types.
|
||||
* @param groupDef the factory returned by {@link #createDefinition createDefinition()}
|
||||
* @param selector the resource location for this factory group
|
||||
*/
|
||||
protected void destroyDefinition(BeanFactory groupDef, String selector) {
|
||||
if (groupDef instanceof ConfigurableBeanFactory) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Factory group with selector '" + selector +
|
||||
"' being released, as there are no more references to it");
|
||||
}
|
||||
((ConfigurableBeanFactory) groupDef).destroySingletons();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* We track BeanFactory instances with this class.
|
||||
*/
|
||||
private static class BeanFactoryGroup {
|
||||
|
||||
private BeanFactory definition;
|
||||
|
||||
private int refCount = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* BeanFactoryReference implementation for this locator.
|
||||
*/
|
||||
private class CountingBeanFactoryReference implements BeanFactoryReference {
|
||||
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
private BeanFactory groupContextRef;
|
||||
|
||||
public CountingBeanFactoryReference(BeanFactory beanFactory, BeanFactory groupContext) {
|
||||
this.beanFactory = beanFactory;
|
||||
this.groupContextRef = groupContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BeanFactory getFactory() {
|
||||
return this.beanFactory;
|
||||
}
|
||||
|
||||
// Note that it's legal to call release more than once!
|
||||
@Override
|
||||
public void release() throws FatalBeanException {
|
||||
synchronized (bfgInstancesByKey) {
|
||||
BeanFactory savedRef = this.groupContextRef;
|
||||
if (savedRef != null) {
|
||||
this.groupContextRef = null;
|
||||
BeanFactoryGroup bfg = bfgInstancesByObj.get(savedRef);
|
||||
if (bfg != null) {
|
||||
bfg.refCount--;
|
||||
if (bfg.refCount == 0) {
|
||||
destroyDefinition(savedRef, resourceLocation);
|
||||
bfgInstancesByKey.remove(resourceLocation);
|
||||
bfgInstancesByObj.remove(savedRef);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// This should be impossible.
|
||||
logger.warn("Tried to release a SingletonBeanFactoryLocator group definition " +
|
||||
"more times than it has actually been used. Resource name [" + resourceLocation + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2008 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.beans.factory.access.el;
|
||||
|
||||
import javax.el.ELContext;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Simple concrete variant of {@link SpringBeanELResolver}, delegating
|
||||
* to a given {@link BeanFactory} that the resolver was constructed with.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5.2
|
||||
*/
|
||||
public class SimpleSpringBeanELResolver extends SpringBeanELResolver {
|
||||
|
||||
private final BeanFactory beanFactory;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new SimpleSpringBeanELResolver for the given BeanFactory.
|
||||
* @param beanFactory the Spring BeanFactory to delegate to
|
||||
*/
|
||||
public SimpleSpringBeanELResolver(BeanFactory beanFactory) {
|
||||
Assert.notNull(beanFactory, "BeanFactory must not be null");
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BeanFactory getBeanFactory(ELContext elContext) {
|
||||
return this.beanFactory;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2014 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.beans.factory.access.el;
|
||||
|
||||
import java.beans.FeatureDescriptor;
|
||||
import java.util.Iterator;
|
||||
import javax.el.ELContext;
|
||||
import javax.el.ELException;
|
||||
import javax.el.ELResolver;
|
||||
import javax.el.PropertyNotWritableException;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
|
||||
/**
|
||||
* Unified EL {@code ELResolver} that delegates to a Spring BeanFactory,
|
||||
* resolving name references to Spring-defined beans.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5.2
|
||||
* @see org.springframework.web.jsf.el.SpringBeanFacesELResolver
|
||||
*/
|
||||
public abstract class SpringBeanELResolver extends ELResolver {
|
||||
|
||||
/** Logger available to subclasses */
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
|
||||
@Override
|
||||
public Object getValue(ELContext elContext, Object base, Object property) throws ELException {
|
||||
if (base == null) {
|
||||
String beanName = property.toString();
|
||||
BeanFactory bf = getBeanFactory(elContext);
|
||||
if (bf.containsBean(beanName)) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Successfully resolved variable '" + beanName + "' in Spring BeanFactory");
|
||||
}
|
||||
elContext.setPropertyResolved(true);
|
||||
return bf.getBean(beanName);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getType(ELContext elContext, Object base, Object property) throws ELException {
|
||||
if (base == null) {
|
||||
String beanName = property.toString();
|
||||
BeanFactory bf = getBeanFactory(elContext);
|
||||
if (bf.containsBean(beanName)) {
|
||||
elContext.setPropertyResolved(true);
|
||||
return bf.getType(beanName);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(ELContext elContext, Object base, Object property, Object value) throws ELException {
|
||||
if (base == null) {
|
||||
String beanName = property.toString();
|
||||
BeanFactory bf = getBeanFactory(elContext);
|
||||
if (bf.containsBean(beanName)) {
|
||||
if (value == bf.getBean(beanName)) {
|
||||
// Setting the bean reference to the same value is alright - can simply be ignored...
|
||||
elContext.setPropertyResolved(true);
|
||||
}
|
||||
else {
|
||||
throw new PropertyNotWritableException(
|
||||
"Variable '" + beanName + "' refers to a Spring bean which by definition is not writable");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadOnly(ELContext elContext, Object base, Object property) throws ELException {
|
||||
if (base == null) {
|
||||
String beanName = property.toString();
|
||||
BeanFactory bf = getBeanFactory(elContext);
|
||||
if (bf.containsBean(beanName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext elContext, Object base) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getCommonPropertyType(ELContext elContext, Object base) {
|
||||
return Object.class;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the Spring BeanFactory to delegate bean name resolution to.
|
||||
* @param elContext the current ELContext
|
||||
* @return the Spring BeanFactory (never {@code null})
|
||||
*/
|
||||
protected abstract BeanFactory getBeanFactory(ELContext elContext);
|
||||
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
/**
|
||||
* Support classes for accessing a Spring BeanFactory from Unified EL.
|
||||
*/
|
||||
package org.springframework.beans.factory.access.el;
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
/**
|
||||
* Helper infrastructure to locate and access bean factories.
|
||||
*
|
||||
* <p><b>Note: This package is only relevant for special sharing of bean
|
||||
* factories, for example behind EJB facades. It is <i>not</i> used in a
|
||||
* typical web application or standalone application.</b>
|
||||
*/
|
||||
package org.springframework.beans.factory.access;
|
||||
|
|
@ -1,241 +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.beans.factory.access;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link SingletonBeanFactoryLocator}.
|
||||
*
|
||||
* @author Colin Sampaleanu
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class SingletonBeanFactoryLocatorTests {
|
||||
private static final Class<?> CLASS = SingletonBeanFactoryLocatorTests.class;
|
||||
private static final String REF1_XML = CLASS.getSimpleName() + "-ref1.xml";
|
||||
|
||||
@Test
|
||||
public void testBasicFunctionality() {
|
||||
SingletonBeanFactoryLocator facLoc = new SingletonBeanFactoryLocator(
|
||||
"classpath*:" + ClassUtils.addResourcePathToPackagePath(CLASS, REF1_XML));
|
||||
|
||||
basicFunctionalityTest(facLoc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Worker method so subclass can use it too.
|
||||
*/
|
||||
protected void basicFunctionalityTest(SingletonBeanFactoryLocator facLoc) {
|
||||
BeanFactoryReference bfr = facLoc.useBeanFactory("a.qualified.name.of.some.sort");
|
||||
BeanFactory fac = bfr.getFactory();
|
||||
BeanFactoryReference bfr2 = facLoc.useBeanFactory("another.qualified.name");
|
||||
fac = bfr2.getFactory();
|
||||
// verify that the same instance is returned
|
||||
TestBean tb = (TestBean) fac.getBean("beans1.bean1");
|
||||
assertTrue(tb.getName().equals("beans1.bean1"));
|
||||
tb.setName("was beans1.bean1");
|
||||
BeanFactoryReference bfr3 = facLoc.useBeanFactory("another.qualified.name");
|
||||
fac = bfr3.getFactory();
|
||||
tb = (TestBean) fac.getBean("beans1.bean1");
|
||||
assertTrue(tb.getName().equals("was beans1.bean1"));
|
||||
BeanFactoryReference bfr4 = facLoc.useBeanFactory("a.qualified.name.which.is.an.alias");
|
||||
fac = bfr4.getFactory();
|
||||
tb = (TestBean) fac.getBean("beans1.bean1");
|
||||
assertTrue(tb.getName().equals("was beans1.bean1"));
|
||||
// Now verify that we can call release in any order.
|
||||
// Unfortunately this doesn't validate complete release after the last one.
|
||||
bfr2.release();
|
||||
bfr3.release();
|
||||
bfr.release();
|
||||
bfr4.release();
|
||||
}
|
||||
|
||||
/**
|
||||
* This test can run multiple times, but due to static keyed lookup of the locators,
|
||||
* 2nd and subsequent calls will actuall get back same locator instance. This is not
|
||||
* an issue really, since the contained beanfactories will still be loaded and released.
|
||||
*/
|
||||
@Test
|
||||
public void testGetInstance() {
|
||||
// Try with and without 'classpath*:' prefix, and with 'classpath:' prefix.
|
||||
BeanFactoryLocator facLoc = SingletonBeanFactoryLocator.getInstance(
|
||||
ClassUtils.addResourcePathToPackagePath(CLASS, REF1_XML));
|
||||
getInstanceTest1(facLoc);
|
||||
|
||||
facLoc = SingletonBeanFactoryLocator.getInstance(
|
||||
"classpath*:/" + ClassUtils.addResourcePathToPackagePath(CLASS, REF1_XML));
|
||||
getInstanceTest2(facLoc);
|
||||
|
||||
// This will actually get another locator instance, as the key is the resource name.
|
||||
facLoc = SingletonBeanFactoryLocator.getInstance(
|
||||
"classpath:" + ClassUtils.addResourcePathToPackagePath(CLASS, REF1_XML));
|
||||
getInstanceTest3(facLoc);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Worker method so subclass can use it too
|
||||
*/
|
||||
protected void getInstanceTest1(BeanFactoryLocator facLoc) {
|
||||
BeanFactoryReference bfr = facLoc.useBeanFactory("a.qualified.name.of.some.sort");
|
||||
BeanFactory fac = bfr.getFactory();
|
||||
BeanFactoryReference bfr2 = facLoc.useBeanFactory("another.qualified.name");
|
||||
fac = bfr2.getFactory();
|
||||
// verify that the same instance is returned
|
||||
TestBean tb = (TestBean) fac.getBean("beans1.bean1");
|
||||
assertTrue(tb.getName().equals("beans1.bean1"));
|
||||
tb.setName("was beans1.bean1");
|
||||
BeanFactoryReference bfr3 = facLoc.useBeanFactory("another.qualified.name");
|
||||
fac = bfr3.getFactory();
|
||||
tb = (TestBean) fac.getBean("beans1.bean1");
|
||||
assertTrue(tb.getName().equals("was beans1.bean1"));
|
||||
|
||||
BeanFactoryReference bfr4 = facLoc.useBeanFactory("a.qualified.name.which.is.an.alias");
|
||||
fac = bfr4.getFactory();
|
||||
tb = (TestBean) fac.getBean("beans1.bean1");
|
||||
assertTrue(tb.getName().equals("was beans1.bean1"));
|
||||
|
||||
bfr.release();
|
||||
bfr3.release();
|
||||
bfr2.release();
|
||||
bfr4.release();
|
||||
}
|
||||
|
||||
/**
|
||||
* Worker method so subclass can use it too
|
||||
*/
|
||||
protected void getInstanceTest2(BeanFactoryLocator facLoc) {
|
||||
BeanFactoryReference bfr;
|
||||
BeanFactory fac;
|
||||
BeanFactoryReference bfr2;
|
||||
TestBean tb;
|
||||
BeanFactoryReference bfr3;
|
||||
BeanFactoryReference bfr4;
|
||||
bfr = facLoc.useBeanFactory("a.qualified.name.of.some.sort");
|
||||
fac = bfr.getFactory();
|
||||
bfr2 = facLoc.useBeanFactory("another.qualified.name");
|
||||
fac = bfr2.getFactory();
|
||||
// verify that the same instance is returned
|
||||
tb = (TestBean) fac.getBean("beans1.bean1");
|
||||
assertTrue(tb.getName().equals("beans1.bean1"));
|
||||
tb.setName("was beans1.bean1");
|
||||
bfr3 = facLoc.useBeanFactory("another.qualified.name");
|
||||
fac = bfr3.getFactory();
|
||||
tb = (TestBean) fac.getBean("beans1.bean1");
|
||||
assertTrue(tb.getName().equals("was beans1.bean1"));
|
||||
bfr4 = facLoc.useBeanFactory("a.qualified.name.which.is.an.alias");
|
||||
fac = bfr4.getFactory();
|
||||
tb = (TestBean) fac.getBean("beans1.bean1");
|
||||
assertTrue(tb.getName().equals("was beans1.bean1"));
|
||||
bfr.release();
|
||||
bfr2.release();
|
||||
bfr4.release();
|
||||
bfr3.release();
|
||||
}
|
||||
|
||||
/**
|
||||
* Worker method so subclass can use it too
|
||||
*/
|
||||
protected void getInstanceTest3(BeanFactoryLocator facLoc) {
|
||||
BeanFactoryReference bfr;
|
||||
BeanFactory fac;
|
||||
BeanFactoryReference bfr2;
|
||||
TestBean tb;
|
||||
BeanFactoryReference bfr3;
|
||||
BeanFactoryReference bfr4;
|
||||
bfr = facLoc.useBeanFactory("a.qualified.name.of.some.sort");
|
||||
fac = bfr.getFactory();
|
||||
bfr2 = facLoc.useBeanFactory("another.qualified.name");
|
||||
fac = bfr2.getFactory();
|
||||
// verify that the same instance is returned
|
||||
tb = (TestBean) fac.getBean("beans1.bean1");
|
||||
assertTrue(tb.getName().equals("beans1.bean1"));
|
||||
tb.setName("was beans1.bean1");
|
||||
bfr3 = facLoc.useBeanFactory("another.qualified.name");
|
||||
fac = bfr3.getFactory();
|
||||
tb = (TestBean) fac.getBean("beans1.bean1");
|
||||
assertTrue(tb.getName().equals("was beans1.bean1"));
|
||||
bfr4 = facLoc.useBeanFactory("a.qualified.name.which.is.an.alias");
|
||||
fac = bfr4.getFactory();
|
||||
tb = (TestBean) fac.getBean("beans1.bean1");
|
||||
assertTrue(tb.getName().equals("was beans1.bean1"));
|
||||
bfr4.release();
|
||||
bfr3.release();
|
||||
bfr2.release();
|
||||
bfr.release();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class TestBean {
|
||||
|
||||
private String name;
|
||||
|
||||
private List<?> list;
|
||||
|
||||
private Object objRef;
|
||||
|
||||
/**
|
||||
* @return Returns the name.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name The name to set.
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the list.
|
||||
*/
|
||||
public List<?> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list The list to set.
|
||||
*/
|
||||
public void setList(List<?> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the object.
|
||||
*/
|
||||
public Object getObjRef() {
|
||||
return objRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object The object to set.
|
||||
*/
|
||||
public void setObjRef(Object object) {
|
||||
this.objRef = object;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- $Id: beans1.xml,v 1.3 2006/08/20 19:08:40 jhoeller Exp $ -->
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||
|
||||
<beans>
|
||||
|
||||
<bean id="beans1.bean1" class="org.springframework.beans.factory.access.TestBean">
|
||||
<property name="name"><value>beans1.bean1</value></property>
|
||||
</bean>
|
||||
|
||||
<bean id="beans1.bean2" class="org.springframework.beans.factory.access.TestBean">
|
||||
<property name="name"><value>bean2</value></property>
|
||||
<property name="objRef"><ref bean="beans1.bean2"/></property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- $Id: beans2.xml,v 1.3 2006/08/20 19:08:40 jhoeller Exp $ -->
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||
|
||||
<beans>
|
||||
|
||||
<bean id="beans2.bean1" class="org.springframework.beans.factory.access.TestBean">
|
||||
<property name="name"><value>beans2.bean1</value></property>
|
||||
</bean>
|
||||
|
||||
<bean id="beans2.bean2" class="org.springframework.beans.factory.access.TestBean">
|
||||
<property name="name"><value>beans2.bean2</value></property>
|
||||
<property name="objRef"><ref bean="beans1.bean1"/></property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||
|
||||
<!-- We are only using one definition file for the purposes of this test, since we do not have multiple
|
||||
classloaders available in the environment to allow combining multiple files of the same name, but
|
||||
of course the contents within could be spread out across multiple files of the same name withing
|
||||
different jars -->
|
||||
|
||||
<beans>
|
||||
|
||||
<!-- this definition could be inside one beanRefFactory.xml file -->
|
||||
<bean id="a.qualified.name.of.some.sort"
|
||||
class="org.springframework.beans.factory.xml.XmlBeanFactory">
|
||||
<constructor-arg value="org/springframework/beans/factory/access/SingletonBeanFactoryLocatorTests-beans1.xml"/>
|
||||
</bean>
|
||||
|
||||
<!-- while the following two could be inside another, also on the classpath,
|
||||
perhaps coming from another component jar -->
|
||||
|
||||
<bean id="another.qualified.name"
|
||||
class="org.springframework.beans.factory.xml.XmlBeanFactory">
|
||||
<constructor-arg value="org/springframework/beans/factory/access/SingletonBeanFactoryLocatorTests-beans1.xml"/>
|
||||
<constructor-arg ref="a.qualified.name.of.some.sort"/> <!-- parent bean factory -->
|
||||
</bean>
|
||||
|
||||
<alias name="another.qualified.name" alias="a.qualified.name.which.is.an.alias"/>
|
||||
|
||||
</beans>
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- $Id: beans1.xml,v 1.3 2006/08/20 19:08:40 jhoeller Exp $ -->
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||
|
||||
<beans>
|
||||
|
||||
<bean id="beans1.bean1" class="org.springframework.beans.factory.access.TestBean">
|
||||
<property name="name"><value>beans1.bean1</value></property>
|
||||
</bean>
|
||||
|
||||
<bean id="beans1.bean2" class="org.springframework.beans.factory.access.TestBean">
|
||||
<property name="name"><value>bean2</value></property>
|
||||
<property name="objRef"><ref bean="beans1.bean2"/></property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- $Id: beans2.xml,v 1.3 2006/08/20 19:08:40 jhoeller Exp $ -->
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||
|
||||
<beans>
|
||||
|
||||
<bean id="beans2.bean1" class="org.springframework.beans.factory.access.TestBean">
|
||||
<property name="name"><value>beans2.bean1</value></property>
|
||||
</bean>
|
||||
|
||||
<bean id="beans2.bean2" class="org.springframework.beans.factory.access.TestBean">
|
||||
<property name="name"><value>beans2.bean2</value></property>
|
||||
<property name="objRef"><ref bean="beans1.bean1"/></property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
|
|
@ -28,13 +28,10 @@ import org.apache.commons.logging.Log;
|
|||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.access.BeanFactoryLocator;
|
||||
import org.springframework.beans.factory.access.BeanFactoryReference;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextException;
|
||||
import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.access.ContextSingletonBeanFactoryLocator;
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
|
|
@ -122,34 +119,6 @@ public class ContextLoader {
|
|||
*/
|
||||
public static final String GLOBAL_INITIALIZER_CLASSES_PARAM = "globalInitializerClasses";
|
||||
|
||||
/**
|
||||
* Optional servlet context parameter (i.e., "{@code locatorFactorySelector}")
|
||||
* used only when obtaining a parent context using the default implementation
|
||||
* of {@link #loadParentContext(ServletContext servletContext)}.
|
||||
* Specifies the 'selector' used in the
|
||||
* {@link ContextSingletonBeanFactoryLocator#getInstance(String selector)}
|
||||
* method call, which is used to obtain the BeanFactoryLocator instance from
|
||||
* which the parent context is obtained.
|
||||
* <p>The default is {@code classpath*:beanRefContext.xml},
|
||||
* matching the default applied for the
|
||||
* {@link ContextSingletonBeanFactoryLocator#getInstance()} method.
|
||||
* Supplying the "parentContextKey" parameter is sufficient in this case.
|
||||
*/
|
||||
public static final String LOCATOR_FACTORY_SELECTOR_PARAM = "locatorFactorySelector";
|
||||
|
||||
/**
|
||||
* Optional servlet context parameter (i.e., "{@code parentContextKey}")
|
||||
* used only when obtaining a parent context using the default implementation
|
||||
* of {@link #loadParentContext(ServletContext servletContext)}.
|
||||
* Specifies the 'factoryKey' used in the
|
||||
* {@link BeanFactoryLocator#useBeanFactory(String factoryKey)} method call,
|
||||
* obtaining the parent application context from the BeanFactoryLocator instance.
|
||||
* <p>Supplying this "parentContextKey" parameter is sufficient when relying
|
||||
* on the default {@code classpath*:beanRefContext.xml} selector for
|
||||
* candidate factory references.
|
||||
*/
|
||||
public static final String LOCATOR_FACTORY_KEY_PARAM = "parentContextKey";
|
||||
|
||||
/**
|
||||
* Any number of these characters are considered delimiters between
|
||||
* multiple values in a single init-param String value.
|
||||
|
|
@ -197,12 +166,6 @@ public class ContextLoader {
|
|||
*/
|
||||
private WebApplicationContext context;
|
||||
|
||||
/**
|
||||
* Holds BeanFactoryReference when loading parent factory via
|
||||
* ContextSingletonBeanFactoryLocator.
|
||||
*/
|
||||
private BeanFactoryReference parentContextRef;
|
||||
|
||||
/** Actual ApplicationContextInitializer instances to apply to the context */
|
||||
private final List<ApplicationContextInitializer<ConfigurableApplicationContext>> contextInitializers =
|
||||
new ArrayList<>();
|
||||
|
|
@ -535,34 +498,12 @@ public class ContextLoader {
|
|||
* alternately to also share the same parent context that is visible to
|
||||
* EJBs. For pure web applications, there is usually no need to worry about
|
||||
* having a parent context to the root web application context.
|
||||
* <p>The default implementation uses
|
||||
* {@link org.springframework.context.access.ContextSingletonBeanFactoryLocator},
|
||||
* configured via {@link #LOCATOR_FACTORY_SELECTOR_PARAM} and
|
||||
* {@link #LOCATOR_FACTORY_KEY_PARAM}, to load a parent context
|
||||
* which will be shared by all other users of ContextsingletonBeanFactoryLocator
|
||||
* which also use the same configuration parameters.
|
||||
* <p>The default implementation simply returns {@code null}, as of 5.0.
|
||||
* @param servletContext current servlet context
|
||||
* @return the parent application context, or {@code null} if none
|
||||
* @see org.springframework.context.access.ContextSingletonBeanFactoryLocator
|
||||
*/
|
||||
protected ApplicationContext loadParentContext(ServletContext servletContext) {
|
||||
ApplicationContext parentContext = null;
|
||||
String locatorFactorySelector = servletContext.getInitParameter(LOCATOR_FACTORY_SELECTOR_PARAM);
|
||||
String parentContextKey = servletContext.getInitParameter(LOCATOR_FACTORY_KEY_PARAM);
|
||||
|
||||
if (parentContextKey != null) {
|
||||
// locatorFactorySelector may be null, indicating the default "classpath*:beanRefContext.xml"
|
||||
BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector);
|
||||
Log logger = LogFactory.getLog(ContextLoader.class);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Getting parent context definition: using parent context key of '" +
|
||||
parentContextKey + "' with BeanFactoryLocator");
|
||||
}
|
||||
this.parentContextRef = locator.useBeanFactory(parentContextKey);
|
||||
parentContext = (ApplicationContext) this.parentContextRef.getFactory();
|
||||
}
|
||||
|
||||
return parentContext;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -590,9 +531,6 @@ public class ContextLoader {
|
|||
currentContextPerThread.remove(ccl);
|
||||
}
|
||||
servletContext.removeAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
|
||||
if (this.parentContextRef != null) {
|
||||
this.parentContextRef.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
|
|
@ -16,11 +16,14 @@
|
|||
|
||||
package org.springframework.web.jsf.el;
|
||||
|
||||
import java.beans.FeatureDescriptor;
|
||||
import java.util.Iterator;
|
||||
import javax.el.ELContext;
|
||||
import javax.el.ELException;
|
||||
import javax.el.ELResolver;
|
||||
import javax.el.PropertyNotWritableException;
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.access.el.SpringBeanELResolver;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.jsf.FacesContextUtils;
|
||||
|
||||
|
|
@ -64,18 +67,72 @@ import org.springframework.web.jsf.FacesContextUtils;
|
|||
* @see WebApplicationContextFacesELResolver
|
||||
* @see org.springframework.web.jsf.FacesContextUtils#getRequiredWebApplicationContext
|
||||
*/
|
||||
public class SpringBeanFacesELResolver extends SpringBeanELResolver {
|
||||
public class SpringBeanFacesELResolver extends ELResolver {
|
||||
|
||||
/**
|
||||
* This implementation delegates to {@link #getWebApplicationContext}.
|
||||
* Can be overridden to provide an arbitrary BeanFactory reference to resolve
|
||||
* against; usually, this will be a full Spring ApplicationContext.
|
||||
* @param elContext the current JSF ELContext
|
||||
* @return the Spring BeanFactory (never {@code null})
|
||||
*/
|
||||
@Override
|
||||
protected BeanFactory getBeanFactory(ELContext elContext) {
|
||||
return getWebApplicationContext(elContext);
|
||||
public Object getValue(ELContext elContext, Object base, Object property) throws ELException {
|
||||
if (base == null) {
|
||||
String beanName = property.toString();
|
||||
WebApplicationContext wac = getWebApplicationContext(elContext);
|
||||
if (wac.containsBean(beanName)) {
|
||||
elContext.setPropertyResolved(true);
|
||||
return wac.getBean(beanName);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getType(ELContext elContext, Object base, Object property) throws ELException {
|
||||
if (base == null) {
|
||||
String beanName = property.toString();
|
||||
WebApplicationContext wac = getWebApplicationContext(elContext);
|
||||
if (wac.containsBean(beanName)) {
|
||||
elContext.setPropertyResolved(true);
|
||||
return wac.getType(beanName);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(ELContext elContext, Object base, Object property, Object value) throws ELException {
|
||||
if (base == null) {
|
||||
String beanName = property.toString();
|
||||
WebApplicationContext wac = getWebApplicationContext(elContext);
|
||||
if (wac.containsBean(beanName)) {
|
||||
if (value == wac.getBean(beanName)) {
|
||||
// Setting the bean reference to the same value is alright - can simply be ignored...
|
||||
elContext.setPropertyResolved(true);
|
||||
}
|
||||
else {
|
||||
throw new PropertyNotWritableException(
|
||||
"Variable '" + beanName + "' refers to a Spring bean which by definition is not writable");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadOnly(ELContext elContext, Object base, Object property) throws ELException {
|
||||
if (base == null) {
|
||||
String beanName = property.toString();
|
||||
WebApplicationContext wac = getWebApplicationContext(elContext);
|
||||
if (wac.containsBean(beanName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext elContext, Object base) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getCommonPropertyType(ELContext elContext, Object base) {
|
||||
return Object.class;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
|
|
@ -230,34 +230,6 @@ public class ContextLoaderTests {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContextLoaderWithDefaultContextAndParent() throws Exception {
|
||||
MockServletContext sc = new MockServletContext("");
|
||||
sc.addInitParameter(ContextLoader.CONFIG_LOCATION_PARAM,
|
||||
"/org/springframework/web/context/WEB-INF/applicationContext.xml "
|
||||
+ "/org/springframework/web/context/WEB-INF/context-addition.xml");
|
||||
sc.addInitParameter(ContextLoader.LOCATOR_FACTORY_SELECTOR_PARAM,
|
||||
"classpath:org/springframework/web/context/ref1.xml");
|
||||
sc.addInitParameter(ContextLoader.LOCATOR_FACTORY_KEY_PARAM, "a.qualified.name.of.some.sort");
|
||||
ServletContextListener listener = new ContextLoaderListener();
|
||||
ServletContextEvent event = new ServletContextEvent(sc);
|
||||
listener.contextInitialized(event);
|
||||
WebApplicationContext context = (WebApplicationContext) sc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
|
||||
assertTrue("Correct WebApplicationContext exposed in ServletContext",
|
||||
context instanceof XmlWebApplicationContext);
|
||||
LifecycleBean lb = (LifecycleBean) context.getBean("lifecycle");
|
||||
assertTrue("Has father", context.containsBean("father"));
|
||||
assertTrue("Has rod", context.containsBean("rod"));
|
||||
assertTrue("Has kerry", context.containsBean("kerry"));
|
||||
assertTrue("Not destroyed", !lb.isDestroyed());
|
||||
assertTrue(context.containsBean("beans1.bean1"));
|
||||
assertTrue(context.isTypeMatch("beans1.bean1", org.springframework.beans.factory.access.TestBean.class));
|
||||
assertTrue(context.containsBean("beans1.bean2"));
|
||||
assertTrue(context.isTypeMatch("beans1.bean2", org.springframework.beans.factory.access.TestBean.class));
|
||||
listener.contextDestroyed(event);
|
||||
assertTrue("Destroyed", lb.isDestroyed());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContextLoaderWithCustomContext() throws Exception {
|
||||
MockServletContext sc = new MockServletContext("");
|
||||
|
|
|
|||
|
|
@ -1641,61 +1641,11 @@ lookups simply provides consistent and more explicit EJB access configuration.
|
|||
|
||||
|
||||
|
||||
[[ejb-implementation]]
|
||||
=== Using Spring's EJB implementation support classes
|
||||
|
||||
|
||||
|
||||
[[ejb-implementation-ejb3]]
|
||||
==== EJB 3 injection interceptor
|
||||
For EJB 3 Session Beans and Message-Driven Beans, Spring provides a convenient
|
||||
interceptor that resolves Spring's `@Autowired` annotation in the EJB component
|
||||
class: `org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor`. This
|
||||
interceptor can be applied through an `@Interceptors` annotation in the EJB component
|
||||
class, or through an `interceptor-binding` XML element in the EJB deployment descriptor.
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
@Stateless
|
||||
@Interceptors(SpringBeanAutowiringInterceptor.class)
|
||||
public class MyFacadeEJB implements MyFacadeLocal {
|
||||
|
||||
// automatically injected with a matching Spring bean
|
||||
@Autowired
|
||||
private MyComponent myComp;
|
||||
|
||||
// for business method, delegate to POJO service impl.
|
||||
public String myFacadeMethod(...) {
|
||||
return myComp.myMethod(...);
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
`SpringBeanAutowiringInterceptor` by default obtains target beans from a
|
||||
`ContextSingletonBeanFactoryLocator`, with the context defined in a bean definition file
|
||||
named `beanRefContext.xml`. By default, a single context definition is expected, which
|
||||
is obtained by type rather than by name. However, if you need to choose between multiple
|
||||
context definitions, a specific locator key is required. The locator key (i.e. the name
|
||||
of the context definition in `beanRefContext.xml`) can be explicitly specified either
|
||||
through overriding the `getBeanFactoryLocatorKey` method in a custom
|
||||
`SpringBeanAutowiringInterceptor` subclass.
|
||||
|
||||
Alternatively, consider overriding `SpringBeanAutowiringInterceptor`'s `getBeanFactory`
|
||||
method, e.g. obtaining a shared `ApplicationContext` from a custom holder class.
|
||||
|
||||
|
||||
|
||||
|
||||
[[jms]]
|
||||
== JMS (Java Message Service)
|
||||
|
||||
|
||||
|
||||
|
||||
[[jms-introduction]]
|
||||
=== Introduction
|
||||
Spring provides a JMS integration framework that simplifies the use of the JMS API much
|
||||
|
|
|
|||
Loading…
Reference in New Issue