All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.springframework.jca.context.SpringContextResourceAdapter Maven / Gradle / Ivy

There is a newer version: 6.2.0
Show newest version
/*
 * Copyright 2002-2018 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
 *
 *      https://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.jca.context;

import javax.resource.NotSupportedException;
import javax.resource.ResourceException;
import javax.resource.spi.ActivationSpec;
import javax.resource.spi.BootstrapContext;
import javax.resource.spi.ResourceAdapter;
import javax.resource.spi.ResourceAdapterInternalException;
import javax.resource.spi.endpoint.MessageEndpointFactory;
import javax.transaction.xa.XAResource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

/**
 * JCA 1.7 {@link javax.resource.spi.ResourceAdapter} implementation
 * that loads a Spring {@link org.springframework.context.ApplicationContext},
 * starting and stopping Spring-managed beans as part of the ResourceAdapter's
 * lifecycle.
 *
 * 

Ideal for application contexts that do not need any HTTP entry points * but rather just consist of message endpoints and scheduled jobs etc. * Beans in such a context may use application server resources such as the * JTA transaction manager and JNDI-bound JDBC DataSources and JMS * ConnectionFactory instances, and may also register with the platform's * JMX server - all through Spring's standard transaction management and * JNDI and JMX support facilities. * *

If the need for scheduling asynchronous work arises, consider using * Spring's {@link org.springframework.jca.work.WorkManagerTaskExecutor} * as a standard bean definition, to be injected into application beans * through dependency injection. This WorkManagerTaskExecutor will automatically * use the JCA WorkManager from the BootstrapContext that has been provided * to this ResourceAdapter. * *

The JCA {@link javax.resource.spi.BootstrapContext} may also be * accessed directly, through application components that implement the * {@link BootstrapContextAware} interface. When deployed using this * ResourceAdapter, the BootstrapContext is guaranteed to be passed on * to such components. * *

This ResourceAdapter is to be defined in a "META-INF/ra.xml" file * within a Java EE ".rar" deployment unit like as follows: * *

 * <?xml version="1.0" encoding="UTF-8"?>
 * <connector xmlns="http://java.sun.com/xml/ns/j2ee"
 *		 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 *		 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee https://java.sun.com/xml/ns/j2ee/connector_1_5.xsd"
 *		 version="1.5">
 *	 <vendor-name>Spring Framework</vendor-name>
 *	 <eis-type>Spring Connector</eis-type>
 *	 <resourceadapter-version>1.0</resourceadapter-version>
 *	 <resourceadapter>
 *		 <resourceadapter-class>org.springframework.jca.context.SpringContextResourceAdapter</resourceadapter-class>
 *		 <config-property>
 *			 <config-property-name>ContextConfigLocation</config-property-name>
 *			 <config-property-type>java.lang.String</config-property-type>
 *			 <config-property-value>META-INF/applicationContext.xml</config-property-value>
 *		 </config-property>
 *	 </resourceadapter>
 * </connector>
* * Note that "META-INF/applicationContext.xml" is the default context config * location, so it doesn't have to specified unless you intend to specify * different/additional config files. So in the default case, you may remove * the entire {@code config-property} section above. * *

For simple deployment needs, all you need to do is the following: * Package all application classes into a RAR file (which is just a standard * JAR file with a different file extension), add all required library jars * into the root of the RAR archive, add a "META-INF/ra.xml" deployment * descriptor as shown above as well as the corresponding Spring XML bean * definition file(s) (typically "META-INF/applicationContext.xml"), * and drop the resulting RAR file into your application server's * deployment directory! * * @author Juergen Hoeller * @since 2.5 * @see #setContextConfigLocation * @see #loadBeanDefinitions * @see ResourceAdapterApplicationContext */ public class SpringContextResourceAdapter implements ResourceAdapter { /** * Any number of these characters are considered delimiters between * multiple context config paths in a single String value. * @see #setContextConfigLocation */ public static final String CONFIG_LOCATION_DELIMITERS = ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS; /** * The default {@code applicationContext.xml} location. */ public static final String DEFAULT_CONTEXT_CONFIG_LOCATION = "META-INF/applicationContext.xml"; protected final Log logger = LogFactory.getLog(getClass()); private String contextConfigLocation = DEFAULT_CONTEXT_CONFIG_LOCATION; @Nullable private ConfigurableApplicationContext applicationContext; /** * Set the location of the context configuration files, within the * resource adapter's deployment unit. This can be a delimited * String that consists of multiple resource location, separated * by commas, semicolons, whitespace, or line breaks. *

This can be specified as "ContextConfigLocation" config * property in the {@code ra.xml} deployment descriptor. *

The default is "classpath:META-INF/applicationContext.xml". */ public void setContextConfigLocation(String contextConfigLocation) { this.contextConfigLocation = contextConfigLocation; } /** * Return the specified context configuration files. */ protected String getContextConfigLocation() { return this.contextConfigLocation; } /** * Return a new {@link StandardEnvironment}. *

Subclasses may override this method in order to supply * a custom {@link ConfigurableEnvironment} implementation. */ protected ConfigurableEnvironment createEnvironment() { return new StandardEnvironment(); } /** * This implementation loads a Spring ApplicationContext through the * {@link #createApplicationContext} template method. */ @Override public void start(BootstrapContext bootstrapContext) throws ResourceAdapterInternalException { if (logger.isDebugEnabled()) { logger.debug("Starting SpringContextResourceAdapter with BootstrapContext: " + bootstrapContext); } this.applicationContext = createApplicationContext(bootstrapContext); } /** * Build a Spring ApplicationContext for the given JCA BootstrapContext. *

The default implementation builds a {@link ResourceAdapterApplicationContext} * and delegates to {@link #loadBeanDefinitions} for actually parsing the * specified configuration files. * @param bootstrapContext this ResourceAdapter's BootstrapContext * @return the Spring ApplicationContext instance */ protected ConfigurableApplicationContext createApplicationContext(BootstrapContext bootstrapContext) { ResourceAdapterApplicationContext applicationContext = new ResourceAdapterApplicationContext(bootstrapContext); // Set ResourceAdapter's ClassLoader as bean class loader. applicationContext.setClassLoader(getClass().getClassLoader()); // Extract individual config locations. String[] configLocations = StringUtils.tokenizeToStringArray(getContextConfigLocation(), CONFIG_LOCATION_DELIMITERS); loadBeanDefinitions(applicationContext, configLocations); applicationContext.refresh(); return applicationContext; } /** * Load the bean definitions into the given registry, * based on the specified configuration files. * @param registry the registry to load into * @param configLocations the parsed config locations * @see #setContextConfigLocation */ protected void loadBeanDefinitions(BeanDefinitionRegistry registry, String[] configLocations) { new XmlBeanDefinitionReader(registry).loadBeanDefinitions(configLocations); } /** * This implementation closes the Spring ApplicationContext. */ @Override public void stop() { logger.debug("Stopping SpringContextResourceAdapter"); if (this.applicationContext != null) { this.applicationContext.close(); } } /** * This implementation always throws a NotSupportedException. */ @Override public void endpointActivation(MessageEndpointFactory messageEndpointFactory, ActivationSpec activationSpec) throws ResourceException { throw new NotSupportedException("SpringContextResourceAdapter does not support message endpoints"); } /** * This implementation does nothing. */ @Override public void endpointDeactivation(MessageEndpointFactory messageEndpointFactory, ActivationSpec activationSpec) { } /** * This implementation always returns {@code null}. */ @Override @Nullable public XAResource[] getXAResources(ActivationSpec[] activationSpecs) throws ResourceException { return null; } @Override public boolean equals(@Nullable Object other) { return (this == other || (other instanceof SpringContextResourceAdapter && ObjectUtils.nullSafeEquals(getContextConfigLocation(), ((SpringContextResourceAdapter) other).getContextConfigLocation()))); } @Override public int hashCode() { return ObjectUtils.nullSafeHashCode(getContextConfigLocation()); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy