1. /*
  2. * Copyright 2002-2004 the original author or authors.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.springframework.remoting.rmi;
  17. import java.io.IOException;
  18. import java.rmi.NotBoundException;
  19. import org.springframework.aop.framework.ProxyFactory;
  20. import org.springframework.beans.factory.FactoryBean;
  21. /**
  22. * Factory bean for RMI proxies, supporting both conventional RMI services and
  23. * RMI invokers. Behaves like the proxied service when used as bean reference,
  24. * exposing the specified service interface. Proxies will throw RemoteAccessException
  25. * on remote invocation failure instead of RMI's RemoteException.
  26. *
  27. * <p>The service URL must be a valid RMI URL like "rmi://localhost:1099/myservice".
  28. * RMI invokers work at the RmiInvocationHandler level, needing only one stub
  29. * for any service. Service interfaces do not have to extend java.rmi.Remote or
  30. * throw RemoteException. Of course, in and out parameters have to be serializable.
  31. *
  32. * <p>With conventional RMI services, this proxy factory is typically used with the
  33. * RMI service interface. Alternatively, this factory can also proxy a remote RMI
  34. * service with a matching non-RMI business interface, i.e. an interface that mirrors
  35. * the RMI service methods but does not declare RemoteExceptions. In the latter case,
  36. * RemoteExceptions thrown by the RMI stub will automatically get converted to
  37. * Spring's unchecked RemoteAccessException.
  38. *
  39. * <p>The major advantage of RMI, compared to Hessian and Burlap, is serialization.
  40. * Effectively, any serializable Java object can be transported without hassle.
  41. * Hessian and Burlap have their own (de-)serialization mechanisms, but are
  42. * HTTP-based and thus much easier to setup than RMI.
  43. *
  44. * @author Juergen Hoeller
  45. * @since 13.05.2003
  46. * @see #setServiceInterface
  47. * @see #setServiceUrl
  48. * @see RmiServiceExporter
  49. * @see org.springframework.remoting.RemoteAccessException
  50. * @see java.rmi.RemoteException
  51. * @see java.rmi.Remote
  52. */
  53. public class RmiProxyFactoryBean extends RmiClientInterceptor implements FactoryBean {
  54. private Object serviceProxy;
  55. public void afterPropertiesSet() throws IOException, NotBoundException {
  56. super.afterPropertiesSet();
  57. if (getServiceInterface() == null) {
  58. throw new IllegalArgumentException("serviceInterface is required");
  59. }
  60. this.serviceProxy = ProxyFactory.getProxy(getServiceInterface(), this);
  61. }
  62. public Object getObject() {
  63. return this.serviceProxy;
  64. }
  65. public Class getObjectType() {
  66. return (this.serviceProxy != null) ? this.serviceProxy.getClass() : getServiceInterface();
  67. }
  68. public boolean isSingleton() {
  69. return true;
  70. }
  71. }