Spring - Create an instance of one class using the factory method of another class - spring

I am using Apache Ignite in my Spring project. I want to create an instance of org.apache.ignite.Ignite within my application context using xml configuration. One of the way to create the Ignite object is by using org.apache.ignite.Ignition#start method. My question is, how can i use bean xml configuration to create an instance of Ignite from Ignition#start.
<!-- Implements Ignite interface -->
<bean class="org.apache.ignite.internal.IgniteKernal">
</bean>
<!-- Returns instance of Ignite as org.apache.ignite.internal.IgniteKernal -->
<bean id="ignitionIgniteKernal" class="org.apache.ignite.Ignition" factory-method="start">
<constructor-arg ref="refToConfig" />
</bean>

Try using the Spring cache Manager.
http://apacheignite.gridgain.org/docs/spring-caching
As per documentation
The embedded node can be started by SpringCacheManager itself. In this case you will need to provide a path to Ignite configuration XML file or IgniteConfiguration bean via configurationPath or configuration properties respectively (see examples below). Note that setting both is illegal and results in IllegalArgumentException.
So the application context brings up the cache and then spring cache manager manages the cache via annotation or explicit addition.
Hope this helps.

According to the spring documentation, the "ignitionIgniteKernal" bean definition above is exactly how you would create an instance of org.apache.ignite.internal.IgniteKernal. Ref:
If the "class" attribute is present, the factory method will be a
static method on the class specified by the "class" attribute on this
bean definition. Often this will be the same class as that of the
constructed object - for example, when the factory method is used as
an alternative to a constructor. However, it may be on a different
class. In that case, the created object will not be of the class
specified in the "class" attribute. This is analogous to FactoryBean
behavior.

Related

Delay spring xml imports

I have an application where I have to read all application properties from properties files. Then override them from a external cache framework. Then initialize spring beans.
I am using Java Config of spring to read properties and override them. And using #import to load xml files. But xml files import as soon as context starts loading, resulting all the xml beans being initialized.
So is there a way I can delay xml files import until I load all the properties first?
You can use the following code.
<beans default-lazy-init="true">
<!-- no beans will be pre-instantiated... -->
</beans>
or individually add lazy-init on beans which you don't want to load.
Or
There are lot of ways you can achieve your requirement One of which can be use of depends-on or #DependsOn if you are looking for annotation based configuration,
You can read property file after that you can create a cache bean and use
depends-on to let the container know you bean is depending on some other bean you can initialise a cache bean and use the same as you see fit.
See this example for better clearity.
<bean id="primaryBean" depends-on="cacheBean"></bean>
Now IoC guarantees that depending bean will be created before the bean which depends on this bean, So you will have an instance of this bean, and can use it.
Other than this you can implement LifeCycle interface
public interface Lifecycle {
void start();
void stop();
boolean isRunning();
}
For more references you can refer spring docs.

Spring Config Client XML equivalent of #RefreshScope

We have an existing Spring MVC application (non Spring-boot application) with all (or most) of the beans configured in the XML. We wanted to use this as a Spring Cloud Config Client (we have a Spring Boot application acting as config server).
In this regard, what is the XML equivalent of configuring the beans in XML with refresh scope (same as #RefreshScope annotation). Tried configuring the RefreshScope as bean and using scope="refresh" but could see that the beans are not reflected with new values after peforming /refresh endpoint (from actuator)
Any help on this is highly appreciated
As pointed out in other answers 'refresh' scope is just another scope. However there's an issue where the bean properties are not updated with new values after /refresh call - if you define and inject properties in XML. More on the issue here. However the bean (i.e. actually the proxy) is instantiated after each /refresh call - but you need "aop:scoped-proxy" config since bean to which you inject the 'refresh' scoped bean, could be on a different scope. i.e.
<bean name="xmlValueBean" class="me.fahimfarook.xml.XMLValueBean" scope="refresh">
<aop:scoped-proxy proxy-target-class="true" />
</bean>
Well if you want to use #RefreshScope in core Spring(also Spring MVC) as people already pointed out, you have to implement the scope yourself also.
I also had the same dilemma and I did, I also wrote a blog about it, you can find there all the implementation details.
You can also use Spring Boot Configuration Server with your Spring MVC application, if you like to.
#RefreshScope for Spring MVC
#RefreshScope is just another scope. Look at how the RefreshScope class is implemented. It is creating a new scope named "refresh".
That means you should be able to use the new scope in your XML configuration, like this.
<bean id = "..." class = "..." scope = "refresh">
</bean>

how does scoped proxy works internally in Spring

consider a case when a prototype-scoped bean is injected into a singleton scoped bean,
when we try to access prototype-scoped bean using the singleton-scoped bean, we are returned with the same bean every time i.e. the bean injected at the time of singleton initialization.
if we want to get different instances everytime we use a scoped proxy.
I did not get the concept how this scoped proxy works behind the stage and how it magically gives us a new instance even if the bean is present inside a singleton.
From the Spring documentation:
3.4.4.5. Scoped beans as dependencies
Being able to define a bean scoped to a HTTP request or Session (or indeed a custom scope of your own devising) is all very well, but one of the main value-adds of the Spring IoC container is that it manages not only the instantiation of your objects (beans), but also the wiring up of collaborators (or dependencies). If you want to inject a (for example) HTTP request scoped bean into another bean, you will need to inject an AOP proxy in place of the scoped bean. That is, you need to inject a proxy object that exposes the same public interface as the scoped object, but that is smart enough to be able to retrieve the real, target object from the relevant scope (for example a HTTP request) and delegate method calls onto the real object.
…
To create such a proxy, you need only to insert a child element into a scoped bean definition (you may also need the CGLIB library on your classpath so that the container can effect class-based proxying; you will also need to be using Appendix A, XML Schema-based configuration). So, just why do you need this element in the definition of beans scoped at the request, session, globalSession and 'insert your custom scope here' level? The reason is best explained by picking apart the following bean definition (please note that the following 'userPreferences' bean definition as it stands is incomplete):
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
<bean id="userManager" class="com.foo.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>

Should a bean be initialized even if it does not have auto-wiring annotations?

If I have a bean defined in an xml file like so :
<bean id="myBean" class="com.myClass">
</bean>
Should "myBean" be autowired, ie should the class "com.myClass" be initialized by Spring ?
I have no Spring annotations in "com.myClass" but the class still seems to be initialized because it is declared in an xml file.
Yes, it is normal that your class to be initialised even though auto-wiring is not stated. The reason for this is:
Declared Spring beans have a life-cycle and the first step in this life-cycle is for Spring to initialise the bean.
The basic life-cycle is as follows:
Initialise Bean
Insert values
Calling certain methods depending on which interfaces you implement. This is useful for further custom initialisation and configuration.
Now your bean is ready for use by your application and will stay in the application context until your application context is destroyed.
Finally, if you implement the DisposableBean interface, the destroy method is called for any de-initialisation process that you may require.
This depends on whether you have any other beans that want Spring to inject myBean into them. If no one uses your bean, you can omit it.

Spring Standard Bean Injection vs. Autowiring

As far as I understand When Using Dependency Injection all bean are initializing on Start.
<bean id="userPreferences" class="com.foo.UserPreferences">
</bean>
<!-- a singleton-scoped bean injected to the above bean -->
<bean id="userService" class="com.foo.SimpleUserService">
<!-- a reference to the userPreferences bean -->
<property name="userPreferences" ref="userPreferences"/>
</bean>
and the configuration above means that userService and userPreferences created when application starts. Is it correct?
When using Autowiring and using <context:component-scan>
public class SimpleUserService{
#Autowired
UserPreferences userPreferences;
//omitted
}
1) Is userPreference created on Application init?
2) What is the default scope for bean injected by autowire and how can we change it?
3) How affects bean creation and bean injection?
Hope I made myself clear.
First of all you should add #Service or #Component to the SimpleUserService class.
1 Yes, the ONE instance of UserPreferences is created at application intialization
2 Default scope is singleton, You can change it with the #Scope annotation (#See Spring Reference: 3.11.4.4 Specifying bean scope)
3 Component scan and XML configuration work in the same way (life cycle)
Maybe you should spend some time in understanding the Spring life cycle. You need to understand that Spring works a bit in this way (not 100% correct):
first it creates a pool of beans
then it injects the properties into the beans
But it does NOT work this way: taking a class, look what references it needs creating this references (recursive) and then creating the class.
If you understand this, then you will also understand, that the #Scope of a bean is defined at the bean declaration/class, but not at the references.
1) Is userPreference created on
Application init?
In either case userPreferences is initialized when Spring Context is loaded. You can change this behavior by adding lazy-init="true" to the bean configuration.
2) What is the default scope for bean
injected by autowire and how can we
change it?
The scope of what is injected is all beans loaded into Spring. If you import an XML configuration from another project, it too would be included. I'm not sure if you can limit your scope.
3) How affects bean creation and bean
injection?
Whether is autowired, or configured via XML, the behavior should be the same. I prefer explicitly defining dependencies over automatic annotations. Then again I also like strongly typed languages.
the configuration above means that userService and userPreferences created when application starts. Is it correct?
Yes
Is userPreference created on Application init?
Yes
What is the default scope for bean injected by autowire and how can we change it?
The default scope is always "singleton". This can be changed either using #Scope with #Bean or the scope XML attribute on <bean>.
How affects bean creation and bean injection?
This isn't a clear question. If you change the bean scope, you change when it gets created (start of application, on each request, on each session, etc). The wiring configuration remains the same, only the lifecycle changes.
The #autowired notation is an obsolete way to say #inject. THe latter is a feature of JavaEE 6.
stackoverflow.com/questions/7142622/what-is-the-difference-between-inject-and-autowired-in-spring-framework-which

Resources