I have two FactoryBeans creating proxies for existing beans in the application context.
FactoryBeanA.getObject() is invoked as part of the singleton pre-instantiation, and it attempts to autowire the returned instance.
This autowiring needs a bean that is defined by FactoryBeanB, which has not yet been configured (had properties injected).
Can this be controlled in such a way, that I am sure both FactoryBeans are fully configured (properties injected) before any beans are attempted instantiated?
Edit:
Autowiring from FactoryBeanA objects have worked fine until I changed FactoryBeanB to require a property to be injected. After this change, I see autowiring for the A-bean try to invoke FactoryBeanB.getObject(), but this fails as properties has not yet been injected.
Problem was actually caused by my own mistake. FactoryBeanB was not configured properly as I thought.
Related
I have a Spring bean with scope session. This bean holds a reference to another singleton bean which is not serializable. What is the best approach if I want to serialize the session scoped bean?
The same question is already asked here: Spring session-scoped beans (controllers) and references to services, in terms of serialization
The accepted answer is that:
[...]this issue is resolved in spring 3.0 by providing a proxy of non-serializable beans, which obtains an instance from the current application context
As far as I understand the speaker in the linked video it should "just work". But in my case it doesn't! When I try to serialize my session scoped bean i get a NotSerializableException.
How can I solve this problem?
You need to instruct Spring to create that proxy. In XML-based config, via <aop:scoped-proxy/> tag, in component-scan mode via annotation:
#Scope(proxyMode = ScopedProxyMode.INTERFACES)
on your controller class.
You may mark singleton reference field as transient. Then check How to execute method after deserialization and load reference from ApplicationContext.
Also, please provide stacktrace.
P.S.
It is not too good idea to use session passivation.
When i want a bean say in the main method I ask for a getBean on the id. Does spring container do the same when we define properties as refs to other beans within a single bean ?
Does spring container do the same when we define properties as refs to
other beans within a single bean
Ultimately yes, Spring does find beans within the application container which match your bean definition. How it does it is something which shouldn't be too much of a concern to most users. Since it's usually enough to know that if you ask for a bean from Spring it'll come wired with all of it's dependencies.
If you're interested in the exact wiring mechanism the source code is the place to learn.
I am using a #configurable annotated Vaadin controller together with my Spring context, and it is working fine - except when I need to restart Tomcat, and the sessions are deserialized. Then I get this for my Vaadin app:
org.springframework.beans.factory.wiring.BeanConfigurerSupport BeanFactory has not been set on BeanConfigurerSupport: Make sure this configurer runs in a Spring container. Unable to configure bean of type [web.vaadin.ui.BackOfficeApplication]. Proceeding without injection.
I am thinking that this can be because the vaadin app is reserializing before the spring bean factory has a chance to?
(I am using CTW - aspectj and Spring 3.1.1.RELEASE)
Note:
It seems in the log that these errors come before the "Root WebApplicationContext: initialization started". How can it be that the beans are being autowired before the context initialization is started?
I am not an expert on (de)serialization with Spring and Tomcat, and this is not an answer but might be a workaround.
If BackOfficeApplication is your Vaadin application then there is an alternative to using #Configurable on that class. Instead, create a per-Vaadin Application Spring application context XML file and add this to it to cause your BackOfficeApplication instances to be autowired, etc.:
<bean id="backOfficeApplication"
class="org.dellroad.stuff.vaadin.ContextApplication"
factory-method="get"/>
In general, #Configurable can be more troublesome than normal bean wiring because they require the configuration to occur at object construction rather than allowing the bean factory to do the wiring later on, where it may be better able to detect loops, enforce ordering, etc.
Ideally normal bean wiring should be used for singletons that are initialized once at the beginning of the application and #Configurable should be used for "on the fly" beans created randomly during normal operation.
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
How IOC container helps maintaing objects by creating once and injecting when required???
Read the spring reference about Bean Scopes and about Lazy Initialization:
By default, ApplicationContext
implementations eagerly create and
configure all singleton beans as part
of the initialization process.
Generally, this pre-instantiation is
desirable, because errors in the
configuration or surrounding
environment are discovered
immediately, as opposed to hours or
even days later. When this behavior is
not desirable, you can prevent
pre-instantiation of a singleton bean
by marking the bean definition as
lazy-initialized. A lazy-initialized
bean tells the IoC container to create
a bean instance when it is first
requested, rather than at startup.
In XML, this behavior is controlled by
the lazy-init attribute on the
element; for example:
<bean id="lazy" class="com.foo.ExpensiveToCreateBean" lazy-init="true"/>
<bean name="not.lazy" class="com.foo.AnotherBean"/>
It depends how you have configured the specific dependency, you can have singleton, per request, http etc lifecycles