when spring bean is loaded and if i have a constructor and setters which one will be called first? - spring

This is a basic question - when spring bean is loaded and if i have a constructor and setters which one will be called first?
Thanks

The constructor must be called before any setter methods are called. Use the init-method to tell Spring to invoke some logic after the setters are called:
<bean class="my.CoolClass" init-method="startup">
<constructor-arg value="Foo" />
<property name="bar" value="baz" />
</bean>

Doesn't the constructor have to be called first? The setters are instance methods so that can't called until the object is instantiated.

I don't think Spring provides any guarantees about the order in which setters are called. It would be good practice to make your beans work regardless of which order the setters are called. If you want to do some processing after all the setters have been called, you might find that it's convenient to use a post construction method. Or if you are using XML configuration rather than annotations, an initialization method might suit.

I wrote simple XML config and step through Spring source code in debugger.
Seems that with Spring 3.x it's possible to combine constructor-arg and property in XML bean definition (check doCreateBean in AbstractAutowireCapableBeanFactory.java, which call createBeanInstance - constructor and populateBean next - setters).
See also https://softwareengineering.stackexchange.com/questions/149378/both-constructor-and-setter-injection-together-in-spring/

Related

Cyclic dependencies in Spring

IF I have bean A which refer to bean B and bean B depends upon bean A. In this scenario spring throws ObjectCurrentlyInCreationException ,but how internally it happen and on which object it will throw this error.
For Eg:
<bean id='A'>
<ref bean='B'>
</bean>
<bean id='B'>
<ref bean='A'>
</bean>
If your classes A and B have default constructors (A(), B()), I believe everything should go well. Possible dupe of this question: Circular dependency in spring
This is typical example of Circular dependency in Spring. Spring can resolve circular dependencies through setter - injection. Objects are constructed before the setter methods are invoked. The default constructors are needed for both ( rather all the classes involved in circular dependency) classes in order to help Spring construct the empty objects before calling the setter methods

Spring AOP - Error Generating proxies

I'm using spring AOP's around advice to capture processing time of a transaction. I'm getting the following error during application startup
error creating bean "coreMessageResourceAccesor"
Could not generate CGLIB subclass of class
[class org.springframework.context.support.MessageSourceAccessor]:
Common causes of this problem include using a final class or a non-visible class;
nested exception is java.lang.IllegalArgumentException:
Superclass has no null constructors but no arguments were given
I identified what the problem is with the help of this thread. But I cannot change coreMessageResourceAccesor bean to use setter based injection because its using a spring class & that class doesn't have no arg constructor
Below is the configuration for the bean
<bean id="coreMessageSourceAccessor"
class="org.springframework.context.support.MessageSourceAccessor" >
<constructor-arg type="org.springframework.context.MessageSource"
ref="coreMessageSource" />
</bean>
I would really appreciate if someone could help. Thanks for your time.
You don't need really need to configure MessageSourceAccessor accessor as a bean, it's generally easier to instantiate it manually as required. So rather than inject the MessageSourceAccessor into your beans, inject the raw MessageSource, and then wrap it in a MessageSourceAccessor as required (i.e. using new MessageSourceAccessor(messageSource)).
You can then put the advice around the MessageSource rather than the MessageSourceAccessor, which will work better. Also, MessageSourceAccessor will not itself add any significant processing time, it's just a thin wrapper around MessageSource.

Why is there a need to specify the class in both the xml file and in the getBean() method in Spring

This might be an obvious but I'm having a hard time understanding why we need to define the class of a bean in two places....
From the spring reference manual...
...
<bean id="petStore"
class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl">
<property name="accountDao" ref="accountDao"/>
<property name="itemDao" ref="itemDao"/>
<!-- additional collaborators and configuration for this bean go here -->
</bean>
// retrieve configured instance
PetStoreServiceImpl service = context.getBean("petStore", PetStoreServiceImpl.class);
Shouldn't the xml fine be enough for the container to know the class of petStore?
You can use the following method:
context.getBean("petStore")
However, as this returns a java.lang.Object, you'd still need to have a cast:
PetStoreServiceImpl petstore = (PetStoreServiceImpl)context.getBean("petStore");
However, this could lead to problems if your "petStore" bean is not actually a PetStoreServiceImpl, and to avoid casts (which since the advent of Generics are being seen as a bit dirty), you can use the above method to infer the type (and let's spring check whether the bean you're expecting is really of the right class, so hence you've got:
PetStoreServiceImpl service = context.getBean("petStore", PetStoreServiceImpl.class);
Hope that helps.
EDIT:
Personally, I would avoid calling context.getBean() to lookup methods as it goes against the idea of dependency injection. Really, the component that uses the petstore bean should have a property, which can then be injected with the correct component.
private PetStoreService petStoreService;
// setter omitted for brevity
public void someotherMethod() {
// no need for calling getBean()
petStoreService.somePetstoreMethod();
}
Then you can hook up the beans in the application context:
You could also do away with the configuration via XML and use annotation to wire up your beans:
#Autowired
private PetStoreService petStoreService;
As long as you've got
in your spring context, the "petStore" bean defined in your application context will automatically be injected. If you've got more than one bean with the type "PetStoreService", then you'd need to add a qualifier:
#Autowired
#Qualifier("petStore")
private PetStoreService petStoreService;
There's no requirement to specify the class in the getBean() method. It's just a question of safety. Note there's also a getBean() that takes only a class so that you can just look up beans by type instead of needing to know the name.

Spring Dependency injection scope confusion

I am new to Spring DI and i am implimenting DI for the first time in my webapplication.
it seems i am doing somehing wrong and it related the way i am using spring scope.here is my problem
i have a serive class where i am injecting various other object in order to achieve the desired functionality
here is my spring file entries
<bean id="ImportServiceImpl" class="ImportServiceImpl" factory-method="getInstance">
<property name="browseDirectory" ref="browseDirectoryImpl"/>
<property name="xmlUnmarshaller" ref="xmlUnmarshallerImpl"/>
<property name="Adaptar" ref="AdaptarImpl"/>
<property name="DAOService" ref="DAO"/>
</bean>
<bean id="browseDirectoryImpl" class="BrowseDirectoryImpl" factory-method="getInstance" />
<bean id="xmlUnmarshallerImpl" class="XMLUnmarshallerImpl"/>
<bean id="AdaptarImpl" class="AdaptarImpl" factory-method="getInstance"/>
now in my adaptarImpl class i have a refrence to some other object which is being initialized in the constructor
private AdaptarImpl(){
foo=new Foo();
}
now for the first time when the server start and this service run fist time everything is fine foo is being initilized to its proper initialization value but for all other subsequent calls Spring is returing refrence to the previous initialized foo object where i want that for each new request a new instance of foo should be created.
it apperas to me that the factory method being used in the above code factory-method="getInstance"
is being called only once when server called and all other subsequent calles returning same refrence where i want a new instance for every request.
here is my facory method
public static ImportServiceImpl getInstance(){
return new ImportServiceImpl();
}
i know i am doing basics wrong in DI but not sure where it is.I am using Struts2 for MVC and for service layer using Spring DI
any help in this regard will be helpful
Thanks
Umesh
I'm not sure I understand your question, but it sounds like you ought to ask Spring to inject the reference to Foo into your AdapterImpl and make its scope "request". If you need Spring to control object creation, don't call "new".
I think you need to look at
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-factory-scopes
and look at table 3.3.

Making sure a Spring Bean is properly initialised

What is the most concise way of making sure that a Spring bean has all properties set and the init method called?
I'll favour answers which use setter injection and XML configuration, since that's what I'm using right now.
I'm trying to evade the case where I either forget to configure a setter or call the init-method.
In future projects I would favour skaffman's response, but I've chosen the one which suits me right now.
This poll is exactly what you are looking for.
Here are the results:
By using the dependency-check attribute in XML: 11.52%
By using the #Required annotation (or a custom annotation): 21.40%
By using InitializingBean and an assert facility: 23.87%
By using init-method and an assert facility: 14.40%
I don't have to, because I use constructor injection for required properties: 19.34%
I check my dependencies in my business methods: 7.41%
I don't check required dependencies: 34.16%
Use the #Required annotation on the setter methods. Spring will then check that they've all been set without you having to check manually.
Alternatively, annotate your init methods with #PostConstruct, and Spring will invoke them for you.
You can add the dependency-check attribute to your bean definition to ensure that all objects / primitives / both have been set.
<bean id="myBean" class="com.foo.MyBean" dependency-check="objects"/>
Skaffman's answer gives more control, but does introduce a compile-time dependency on Spring which you may / may not want.
Use the following attributes of the beans tag to make sure dependency checking and the init method is called on all beans, but it rather assumes you don't call your method "innit".
<beans default-init-method="init" default-dependency-check="objects">
see link

Resources