Spring 3.0 RmiProxyFactoryBean: how to change serviceUrl at runtime? - spring

I have a bean definition like this:
<bean id="myService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceInterface" value="org.myapp.MyService"/>
<property name="serviceUrl" value="rmi://localhost:1099/myService"/>
</bean>
I retrieve the service bean in this way:
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:rmi-client-config.xml");
MyService myService = context.getBean("myService", MyService.class);
Of course it returns an Instance of "MyService" impl and not RmiProxyFactoryBean.
So how can I change "serviceUrl" parameter using the xml definition above and not manually instancing RmiProxyFactoryBean?

To get the FactoryBean instance instead of the bean created by the factory, use the BeanFactory.FACTORY_BEAN_PREFIX. ie
RmiProxyFactoryBean rpfb = (RmiProxyFactoryBean) contex.getBean("&myService");

Related

Grails initialization

In my Grails app, I need access to configuration exposed by a Java class similar to the below
public class Config {
private Properties properties = new Properties();
static load(String path) {
File configFile = new File(path);
FileReader fileReader = new FileReader(configFile);
properties.load(fileReader);
}
String getProperty(String name) {
properties.getProperty(name);
}
}
I trigger the initialisation of this class in the first line of Bootstrap.groovy by calling Config.load("/conf.properties"). However, the initialization of various Spring beans needs properties that are exposed by Config, but by the time Bootstrap.groovy is executed, Spring initialization has already completed.
So I need to find a way to call Config.load() before construction of the Spring beans, is this possible? I guess there might be an event handler available in /script/_Events.groovy that I could invoke it from, but I'm not sure which handlers are available.
Unfortunately, changing the source code of Config.java isn't an option, and neither is eliminating my usage of this class.
You could try declaring a suitable bean in web-app/WEB-INF/applicationContext.xml, which is the definition of the root web application context as opposed to the GrailsApplication's internal context.
<bean id="initConfig" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass" value="com.example.Config" />
<property name="targetMethod" value="load" />
<property name="arguments">
<list><value>/conf.properties</value></list>
</property>
</bean>
and modify the grailsApplication bean to depend on that:
<bean id="grailsApplication" depends-on="initConfig" class="...">

Get session proxy bean in JSP

I have a session bean like this:
#Component
#Scope(value="session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class MySession { ... }
How can I enable access to this bean in JSP?
I displayed session data in JSP and I got this:
org.springframework.web.context.request.ServletRequestAttributes.DESTRUCTION_CALLBACK.scopedTarget.mySession
scopedTarget.mySession
So, I tried using ${scopedTarget.mySession.qualites}, but it didn't work.
If you expose spring beans as context properties using this view resolver configuration, then it should be possible to access the bean with a value expression such as #{mySession.qualites} directly:
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="exposeContextBeansAsAttributes" value="true"/>
</bean>
As an alternative, expose the spring bean to the view model, by using in the #Controller the #ModelAttribute annotation.

GenericBeanDefinition with MethodInvokingFactoryBean

I want to dynamically create the bean and set some property values returned by the method invocations of other bean.
Without dynamic bean creation, I have the following in my spring config file:
<bean id="mybean" class="com.class.mybean">
<property name="customerName">
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="otherBean" />
<property name="targetMethod" value="getCustomerName()" />
</bean>
</property>
</bean>
With dynamic bean creation, here is my code
#Override
public void postProcessBeanFactory(
ConfigurableListableBeanFactory beanFactory) throws BeansException {
this.factory = beanFactory;
BeanDefinitionRegistry registry = ((BeanDefinitionRegistry )factory);
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(MyBeanClass.class);
beanDefinition.setLazyInit(false);
beanDefinition.setAbstract(false);
beanDefinition.setAutowireCandidate(true);
//beanDefinition.setScope("session");
MutablePropertyValues values = new MutablePropertyValues();
values.addPropertyValue("customerName", ????);
beanDefinition.setPropertyValues(values);
registry.registerBeanDefinition("myDynamicBean",beanDefinition);
}
What is the equivalent way in this case?
Instead of xml bean definition you should use class bean definition. For this purpose you should use #Configuration annotation on a class that defines your application context. Here is an example Spring Configuration

How to add a param to a factory-method of a factory-bean in Spring?

let's say I have a factory bean:
<bean id="myFactory" class="com.company.MyFactory" lazy-init="true">
<property name="myProperty" ref="propA">
</bean>
Let's say propA is a bean injected by IOC used in the factory method. And I have 2 beans generated from this factory:
<bean id="bean1" factory-bean="myFactory" factory-method="instance"/>
<bean id="bean2" factory-bean="myFactory" factory-method="instance"/>
How can I make bean2 to use a different myProperty than bean1 without using a different factory method? Or, how can I pass propA as a parameter to the factory-method from the bean1 or bean2 configuration?
This can be achieved in a slightly different way:
class MyFactory {
public Bean instance(MyProperty myProperty) {
return //...
}
}
Now you can use counterintuitive syntax like following:
<bean id="bean1" factory-bean="myFactory" factory-method="instance">
<constructor-arg ref="propA"/>
</bean>
<bean id="bean2" factory-bean="myFactory" factory-method="instance">
<constructor-arg ref="propB"/>
</bean>
Believe it or not but propA and propB will be used as instance() method arguments.

Manually wiring bean (has autowired dependency): Failed to convert

In a util class I want to use one of my services.
Now this service is wired, but the util isn't.
So in my Util class I do:
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"context.xml"});
UserService userService = (UserService) ((BeanFactory)context).getBean("userServiceWired");
In my context.xml I do:
<bean id="userServiceWired" class="com.daniels.jack.service.userServiceImpl">
<property name="restTemplate" value="restTemplateWired" />
</bean>
<bean id="restTemplateWired" class="org.springframework.web.client.RestTemplate"/>
But I get:
Failed to convert property value of type 'java.lang.String' to required type 'org.springframework.web.client.RestTemplate'
On the UserService userService = ... line.
Use ref instead of value
<property name="restTemplate" ref="restTemplateWired" />

Resources