How to use factory bean to create beans in Camel flow - spring

If I have a spring factory bean can I use this factory bean to create my beans within Camel route ?
<bean id="factoryBean" class = "ABC">
<route id ="someId">
<bean id = "someBean" ref ="factoryBean" method = "factoryMethod">
<bean ref = "someBean" method = "someMethod1" />
<bean ref = "someBean" method = "someMethod2" />
</route>

That is not possible in the <route> as it can only call a bean by either the id or the FQN classname. But a factory bean you can setup in Spring or OSGi Blueprint and then give that an id, which you can then just call from a Camel route.

Related

How Spring Container manage if 2 same bean have different id/name

How Many Objects will be created into container. if configuration will be as given below.
<bean id = "helloWorld" class = "com.tutorialspoint.HelloWorld"><br/>
<property name = "message" value = "Hello World"/>
</bean>
<bean id = "helloWorld1" class = "com.tutorialspoint.HelloWorld">
<property name = "message" value = "Hello World"/>
</bean>
One singleton object per definition in the spring container, if you define N beans then N singleton object of the class will be created.
It will create two instances in your case, by definition Spring container creates a singleton instance per bean.

Dynamically create bean

I have requirement to dynamically create bean, I want to do something like below
context1 in external filesystem
<bean id="env" class="java.lang.String">
<constructor-arg value="dev"/>
</bean>
<import resource="classpath:context2/>"
context2 in classpath as below :
<bean id="#{env}_config" value="some value here"/>
in java when I try to refer to bean dev_config through context1 application context, it gives exception that dev_config bean not found. How can I achieve this?
you need to add context namespace (must have spring-context.jar) , and specify scan attribute and specify the package you want to scan for new beans
<context:component-scan base-package="{quulified name for your package}">
</context:component-scan>
Each class you want to generate a bean for need to be annotated with #Component
#Component
public class MyClass

With constructor autowiring Spring does not throw an exception when there are multiple implementation types

There are interfaces Work and You. There are implementation types WorkImpl and YouImpl and YouImpl2.
I use constructor autowire to inject a You implementation instance in a WorkImpl instance.
Because there are multiple You implementations types, I thought Spring would throw an exception. But Spring instantiates an instance of one of the implementation types, in my case it was YouImpl. This is what I do not understand.
The configuration file is partly,
<bean
id="work"
class="my.test.own.spring_book.WorkImpl"
autowire="constructor"
>
<property name="age" value="52"/>
<property" name="name" value="Foo Bar"></property>
</bean>
<bean
id="you"
class="my.test.own.spring_book.YouImpl"
>
</bean>
<bean
id="you2"
class="my.test.own.spring_book.YouImpl2"
>
</bean>
WorkImpl has one constructor,
public WorkImpl(You you) {
this.you=you;
}
There are few types of autowiring using configuration approach:
byName
byType
constructor
autodetect:- Similar to byType, but type applies to constructor arguments.
Spring container looks at the constructor of the beans on which autowire attribute is set to byType in the XML configuration file. It then tries to match and wire a property if its type matches with exactly one of the beans name in configuration file.
<bean id="you" class="my.test.own.spring_book.YouImpl">
</bean>
<bean id="you2" class="my.test.own.spring_book.YouImpl2">
</bean>
It will match with you as name of parameter used in constructor is you
public WorkImpl(You you) {
this.you=you;
}
In order to avoid this you can use autowire-candidate="false" hence that bean will not take part in autowiring
<!-- This bean will not be injected-->
<bean id="you" class="my.test.own.spring_book.YouImpl" autowiring-candidate="false">
</bean>
<bean id="you2" class="my.test.own.spring_book.YouImpl2">
</bean>
Above is the answer of your question. But I will try to explain more so I can use this answer for future if I forget.
Now suppose you don't give id attribute to the bean or value of id attribute is different than the constructor parameter name.
<bean id="you1" class="my.test.own.spring_book.YouImpl" autowiring-candidate="false">
</bean>
<bean id="you2" class="my.test.own.spring_book.YouImpl2">
</bean>
Spring container searches any bean with type You, yes found two. Do next step
Spring container sees any bean with name(i.e id="you") you. No
It throws exception Unsatisfied dependency Injection
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'work' defined in class path resource [autowire-contructor.xml]: Unsatisfied dependency expressed through constructor argument with index 0 of type
[my.test.own.spring_book.You]: : No unique bean of type [my.test.own.spring_book.You] is defined: expected single matching bean but found 2: [you1, you2]; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException

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.

Spring 3.0 RmiProxyFactoryBean: how to change serviceUrl at runtime?

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");

Resources