Spring中存在大量的工具类,如:RMI相关的。Spring所提供的 RMI的支持大大简化了RMI的开发难度,不过通常我们都是采用配置的方式,通过标准的spring bean来使用它们,这样虽然简化了开发,但是也限制了一些灵活性。因为bean的属性都是在配置时设定的(如RMI客户端中的服务的URL),而有时我 们需要在运行时生成这些属性,这时其实只要我们直接使用这些工具类就可以了。
 要在程序中直接使用RmiProxyFactoryBean,我们就必须了解spring是如何使用这个类为我们生成客户端代理的,然后在程序中使用与spring相同的调用方式。
 RmiProxyFactoryBean是一个工厂类,平时我们通过spring获得的并不是这个工厂类的实例,而是用这个工厂类创建的proxy的实例,这个类实现了spring中标准的FactoryBean接口。FactoryBean接口中定义了三个方法:
                            |  | getObject() Return an instance (possibly shared or independent) of the object managed by this factory.
 | 
                      |  | getObjectType() Return the type of object that this FactoryBean creates, or null if not known in advance.
 | 
                      |  boolean | isSingleton() Is the bean managed by this factory a singleton or a prototype?
 | 
      
 我们通过getBean获取这类工厂Bean(实现了FactoryBean接口的Bean)时,spring并不会返回工厂类的实例,而是调用工厂类的getObject方法并把方法的返回值返回给我们。
 这样你就明白了原来我们获得的RMI的Proxy是通过RmiProxyFactoryBean的getObject方法生成的。
 这时你一定认为下面的程序就可以搞定了:
                …
 RmiProxyFactoryBean proxy=new RmiProxyFactoryBean();             
                proxy.setServiceInterface(Calculator.class);
                proxy.setServiceUrl(url);
                Calculator client=(Calculator)proxy.getObject();           
                System.out.println(client.add(1,1));
                …
 运行程序你会发现上面这段程序并不成功,程序会抛出java.lang.NullPointerException异常。
 问题在哪里呢?研究一下你会发现RmiProxyFactoryBean还实现了spring的
InitializingBean接口,接口中包含一个方法
afterPropertiesSet(),在所有属性注入完成后spring会调用这个方法,因此上面的程序并没有完全正确的模拟spring的调用过程。  修改代码:
 …
 RmiProxyFactoryBean proxy=new RmiProxyFactoryBean();             
                proxy.setServiceInterface(Calculator.class);
                proxy.setServiceUrl(url);
                proxy.afterPropertiesSet();
                Calculator client=(Calculator)proxy.getObject();           
                System.out.println(client.add(1,1));
                …
 这次终于成功了!
 最后,此例告诉大家有时我们可以直接调用spring中的工具类,来完成我们的特殊需求,此时要注意的是正确模拟spring的对bean创建和调用过程。