001/* 002 * Copyright 2002-2012 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.jca.support; 018 019import javax.resource.ResourceException; 020import javax.resource.spi.ConnectionManager; 021import javax.resource.spi.ManagedConnectionFactory; 022 023import org.springframework.beans.factory.FactoryBean; 024import org.springframework.beans.factory.InitializingBean; 025 026/** 027 * {@link org.springframework.beans.factory.FactoryBean} that creates 028 * a local JCA connection factory in "non-managed" mode (as defined by the 029 * Java Connector Architecture specification). This is a direct alternative 030 * to a {@link org.springframework.jndi.JndiObjectFactoryBean} definition that 031 * obtains a connection factory handle from a J2EE server's naming environment. 032 * 033 * <p>The type of the connection factory is dependent on the actual connector: 034 * the connector can either expose its native API (such as a JDBC 035 * {@link javax.sql.DataSource} or a JMS {@link javax.jms.ConnectionFactory}) 036 * or follow the standard Common Client Interface (CCI), as defined by the JCA spec. 037 * The exposed interface in the CCI case is {@link javax.resource.cci.ConnectionFactory}. 038 * 039 * <p>In order to use this FactoryBean, you must specify the connector's 040 * {@link #setManagedConnectionFactory "managedConnectionFactory"} (usually 041 * configured as separate JavaBean), which will be used to create the actual 042 * connection factory reference as exposed to the application. Optionally, 043 * you can also specify a {@link #setConnectionManager "connectionManager"}, 044 * in order to use a custom ConnectionManager instead of the connector's default. 045 * 046 * <p><b>NOTE:</b> In non-managed mode, a connector is not deployed on an 047 * application server, or more specificially not interacting with an application 048 * server. Consequently, it cannot use a J2EE server's system contracts: 049 * connection management, transaction management, and security management. 050 * A custom ConnectionManager implementation has to be used for applying those 051 * services in conjunction with a standalone transaction coordinator etc. 052 * 053 * <p>The connector will use a local ConnectionManager (included in the connector) 054 * by default, which cannot participate in global transactions due to the lack 055 * of XA enlistment. You need to specify an XA-capable ConnectionManager in 056 * order to make the connector interact with an XA transaction coordinator. 057 * Alternatively, simply use the native local transaction facilities of the 058 * exposed API (e.g. CCI local transactions), or use a corresponding 059 * implementation of Spring's PlatformTransactionManager SPI 060 * (e.g. {@link org.springframework.jca.cci.connection.CciLocalTransactionManager}) 061 * to drive local transactions. 062 * 063 * @author Juergen Hoeller 064 * @since 1.2 065 * @see #setManagedConnectionFactory 066 * @see #setConnectionManager 067 * @see javax.resource.cci.ConnectionFactory 068 * @see javax.resource.cci.Connection#getLocalTransaction 069 * @see org.springframework.jca.cci.connection.CciLocalTransactionManager 070 */ 071public class LocalConnectionFactoryBean implements FactoryBean<Object>, InitializingBean { 072 073 private ManagedConnectionFactory managedConnectionFactory; 074 075 private ConnectionManager connectionManager; 076 077 private Object connectionFactory; 078 079 080 /** 081 * Set the JCA ManagerConnectionFactory that should be used to create 082 * the desired connection factory. 083 * <p>The ManagerConnectionFactory will usually be set up as separate bean 084 * (potentially as inner bean), populated with JavaBean properties: 085 * a ManagerConnectionFactory is encouraged to follow the JavaBean pattern 086 * by the JCA specification, analogous to a JDBC DataSource and a JDO 087 * PersistenceManagerFactory. 088 * <p>Note that the ManagerConnectionFactory implementation might expect 089 * a reference to its JCA 1.5 ResourceAdapter, expressed through the 090 * {@link javax.resource.spi.ResourceAdapterAssociation} interface. 091 * Simply inject the corresponding ResourceAdapter instance into its 092 * "resourceAdapter" bean property in this case, before passing the 093 * ManagerConnectionFactory into this LocalConnectionFactoryBean. 094 * @see javax.resource.spi.ManagedConnectionFactory#createConnectionFactory() 095 */ 096 public void setManagedConnectionFactory(ManagedConnectionFactory managedConnectionFactory) { 097 this.managedConnectionFactory = managedConnectionFactory; 098 } 099 100 /** 101 * Set the JCA ConnectionManager that should be used to create the 102 * desired connection factory. 103 * <p>A ConnectionManager implementation for local usage is often 104 * included with a JCA connector. Such an included ConnectionManager 105 * might be set as default, with no need to explicitly specify one. 106 * @see javax.resource.spi.ManagedConnectionFactory#createConnectionFactory(javax.resource.spi.ConnectionManager) 107 */ 108 public void setConnectionManager(ConnectionManager connectionManager) { 109 this.connectionManager = connectionManager; 110 } 111 112 @Override 113 public void afterPropertiesSet() throws ResourceException { 114 if (this.managedConnectionFactory == null) { 115 throw new IllegalArgumentException("Property 'managedConnectionFactory' is required"); 116 } 117 if (this.connectionManager != null) { 118 this.connectionFactory = this.managedConnectionFactory.createConnectionFactory(this.connectionManager); 119 } 120 else { 121 this.connectionFactory = this.managedConnectionFactory.createConnectionFactory(); 122 } 123 } 124 125 126 @Override 127 public Object getObject() { 128 return this.connectionFactory; 129 } 130 131 @Override 132 public Class<?> getObjectType() { 133 return (this.connectionFactory != null ? this.connectionFactory.getClass() : null); 134 } 135 136 @Override 137 public boolean isSingleton() { 138 return true; 139 } 140 141}