001/* 002 * Copyright 2002-2017 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.remoting.rmi; 018 019import javax.naming.NamingException; 020 021import org.springframework.aop.framework.ProxyFactory; 022import org.springframework.beans.factory.BeanClassLoaderAware; 023import org.springframework.beans.factory.FactoryBean; 024import org.springframework.util.Assert; 025import org.springframework.util.ClassUtils; 026 027/** 028 * {@link FactoryBean} for RMI proxies from JNDI. 029 * 030 * <p>Typically used for RMI-IIOP (CORBA), but can also be used for EJB home objects 031 * (for example, a Stateful Session Bean home). In contrast to a plain JNDI lookup, 032 * this accessor also performs narrowing through {@link javax.rmi.PortableRemoteObject}. 033 * 034 * <p>With conventional RMI services, this invoker is typically used with the RMI 035 * service interface. Alternatively, this invoker can also proxy a remote RMI service 036 * with a matching non-RMI business interface, i.e. an interface that mirrors the RMI 037 * service methods but does not declare RemoteExceptions. In the latter case, 038 * RemoteExceptions thrown by the RMI stub will automatically get converted to 039 * Spring's unchecked RemoteAccessException. 040 * 041 * <p>The JNDI environment can be specified as "jndiEnvironment" property, 042 * or be configured in a {@code jndi.properties} file or as system properties. 043 * For example: 044 * 045 * <pre class="code"><property name="jndiEnvironment"> 046 * <props> 047 * <prop key="java.naming.factory.initial">com.sun.jndi.cosnaming.CNCtxFactory</prop> 048 * <prop key="java.naming.provider.url">iiop://localhost:1050</prop> 049 * </props> 050 * </property></pre> 051 * 052 * @author Juergen Hoeller 053 * @since 1.1 054 * @see #setServiceInterface 055 * @see #setJndiName 056 * @see #setJndiTemplate 057 * @see #setJndiEnvironment 058 * @see #setJndiName 059 * @see JndiRmiServiceExporter 060 * @see org.springframework.remoting.RemoteAccessException 061 * @see java.rmi.RemoteException 062 * @see java.rmi.Remote 063 * @see javax.rmi.PortableRemoteObject#narrow 064 */ 065public class JndiRmiProxyFactoryBean extends JndiRmiClientInterceptor 066 implements FactoryBean<Object>, BeanClassLoaderAware { 067 068 private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); 069 070 private Object serviceProxy; 071 072 073 @Override 074 public void setBeanClassLoader(ClassLoader classLoader) { 075 this.beanClassLoader = classLoader; 076 } 077 078 @Override 079 public void afterPropertiesSet() throws NamingException { 080 super.afterPropertiesSet(); 081 Class<?> ifc = getServiceInterface(); 082 Assert.notNull(ifc, "Property 'serviceInterface' is required"); 083 this.serviceProxy = new ProxyFactory(ifc, this).getProxy(this.beanClassLoader); 084 } 085 086 087 @Override 088 public Object getObject() { 089 return this.serviceProxy; 090 } 091 092 @Override 093 public Class<?> getObjectType() { 094 return getServiceInterface(); 095 } 096 097 @Override 098 public boolean isSingleton() { 099 return true; 100 } 101 102}