is it possible to inject spring beans into a polling filter class (FClass) controlled by a scheduler job?
i don't quite understand how singleton applies here.
i understand spring beans are singleton so in order to inject the spring beans into class FClass. i need to define FClass as a bean and add the DI as property etc..
so how do i know if FClass should be a singleton? i assume only classes that are singletons can be created and beans and have DI done to them.
my problem is :
i need to be able to inject my facade bean xfacade into FClass. x_facacde handles the dao object. it has Y_dao and a Z_hibernate session beans injected as DI.
when i tried to create a spring bean of StatusPollingFilter (FClass) and injected the facade bean - i got a null and the setter is never called for the injection in debug mode.
the problem:
i'm thought it might be something to do with the thread / scheduler nature of StatusPollingFilter, and since spring beans are singletons it might not work due to that.
i'm thinking of creating a factory for the StatusPollingFilter (FClass). but need to know if this is correct thing and i'm on right track before i do too much work and realize even that doesn't work as the problem might be somewhere else. ideally i just want to update a table in the easiest possible way. but i have to use hibernate as the DAO exists but hibernate is configured using
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
with /hibernate/TopoObject.hbm.xml
files.
so no matter how i try this i always get null pointer exception on session or injected facade bean.
reading some of the QA's here seems like because StatusPollingFilter is instantiated using the scheduler and not spring it cant be aware of the DI beans. so would the above factory pattern help here.
I may have an additional problem but i'll cross that bridge when i come to it. but just to mention briefly, in case anyone is aware of issues that i might hit ... not sure what / how the scheduler would invoke the factory for an instance as its all controlled by 3rd party api - which invokes a StatusPollingFilter but i'm assuming if i pass in the factory as the class and parameter it would find its way through... but initial part is the main question. please ignore the latter waffle. thanks in advance.
Actually :
i assume only classes that are singletons can be created
is where you are wrong.
A bean is just a class that you let spring instantiate. By default, they are created as singleton but you can specify the scope on your bean using the attribute scope (quite surprisingly). The value you can specify are those specified in the documentation here
So one thing you have to be careful with is the injection of beans scoped as prototype or request into singletons.
having read more - i have come across the ans.
because the StatusPollingFilter object is under control of scheduler (i knew that scheduler had something to do with it) then it is unaware of the spring beans which is why i keep getting null when i try injecting the bean.
i created a class:
ApplicationContextProvider implements ApplicationContextAware
added static access
private static ApplicationContext appContext;
did a setter for it :
public void setApplicationContext(ApplicationContext context)
{
appContext = context;
}
and added
public static Object getBean(String beanName) throws BeansException
{
return appContext.getBean(beanName);
}
used in code as :
EvoTAMDAOFacade evoDao = (EvoTAMDAOFacade) ApplicationContextProvider.getBean("evoDaoFacade");
i now have access to the facade bean and all injected beans into facade.
i still have an issue with hibernate session but thats prob due to some other issue.
pt here is i don't have access to the bean as its not in control of the spring container so i needed to somehow get it , probably could have done it via the factory method but why mess around when there a simpler way.
thanks for help by anyone who may have posted or tried to understand my problem.
Related
Spring is auto-wiring in a request parameter - let's call it "bob".
I don't know where nor how it is doing this, so I cannot debug it. What spring specific code (using intellij, so I can at lest set a conditional) would be appropriate to find where the auto-wiring of the request parameter is happening, so I can work out what the system is doing?
I think I understood the question, so I will try to answer it as best as I can.
You are facing a dilemma of choosing between managing your instances, or letting Spring manage them. If you let Spring manage dependency injection, you will often face situations where you wish you had more fine control over the beans lifecycle.
By default, Spring beans are "singletons", which means that only one
instance of that object will be created, and every class that demands
a dependency injection of that object will receive the same instance.
The first step on beans lifecycle is its construction. You can setup a breakpoint to catch that moment on any method annotated with #PostConstruct. This article describes the need of running some code on bean initialization, and how it is solved by this annotation. For example:
public class AnyBean {
#PostConstruct
public void init(){
// any code or breakpoints inserted here will
// be run whenever an instance of this bean is created.
// if a singleton bean, only one instance is created and,
// only one #PostConstruct will be called.
// If a bean is a prototype bean, a new instance will be created
// for every dependency injection, and hence one #PostConstruct
// will be called for each.
}
}
I'm new to Spring and a little confused about how it works. I get that I can use the application context to instantiate beans and have them populated. However, is the idea that I should be able to just write Bean b = new Bean() and then have Spring to somehow automagically populate that Bean?
I'm experimenting with Spring in a web application, and as far as I can see I need to inject the ApplicationContext into, say, the servlets to be able to instantiate other beans (services, daos etc.) from there. It's a bit cumbersome, but probably works.
However, is Spring meant to be able to hook into any object instantiation which happens on classes defined as beans in applicationContext.xml?
Spring is an Inversion of Control container. A bean is an object whose life cycle is managed by Spring. If you want Spring to populate an object, it needs to go through Spring, ie. it needs to be bean.
is Spring meant to be able to hook into any object instantiation
which happens on classes defined as beans in applicationContext.xml?
Spring doesn't hook into anything. You configure your beans and the relationships between them with Spring and Spring handles creating the instances and linking them up.
For domain objects, Spring provides a solution via the #Configurable annotation: http://docs.spring.io/spring/docs/4.0.0.RELEASE/spring-framework-reference/htmlsingle/#aop-atconfigurable
It requires compile- or load-time-weaving and, thus, introduces some additional complexity but having the convenience of using the standard new Bean() syntax plus Spring's autowiring is worth it in my opinion.
Alternatively, you could define your domain objects as beans with prototype scope and use some factory to create them using the Spring ApplicationContext.getBean() method. With a scope of prototype a new instance will be returned every time and since you go through the ApplicationContext, Spring will do all the dependency injection magic as usual.
As for services and other beans with singleton scope, you would typically NOT retrieve them by first injecting the ApplicationContext and using it but instead you would inject them via either a constructor, setter or annotation-based strategy. The documentation covers that in detail: http://docs.spring.io/spring/docs/4.0.0.RELEASE/spring-framework-reference/htmlsingle/#beans-factory-collaborators
I am new Spring AOP and Aspectj. I have seen various posts related to injected bean in an aspect being null and I have run into a similar problem. I am still not clear how I should proceed to get past the problem I am currently encountering.
Issue: Currently we are using Spring 3.2.3 and all injection is through Annotation. In my case, the dependent bean is injected properly by Spring but at the point of execution the injected bean is NULL. BTW, this doesn't happen all the time but what I can say is the stack trace when it fails and when it succeeds is slightly different. When the injected bean is not null (I can successfully use the injected bean service), the call to the before advice (in the aspect) always happens before the target method is called as it should.When the injected bean is NULL, the call to the aspect is from the first statement of the target method. At this point, I think another aspect is instantiated and has no reference to the injected bean. Here is the aspect I have created:
#Component
#Aspect
public class Enable{
private NameService nameService;
#Autowired
public void SetNameService(NameSerice service){
// service is injected properly
this.nameSerice = service;
}
#Before("* *.*(..)")
public void callBefore(JoinPoint jp){
//sometimes nameService is null and sometimes it not not
this.nameService.lookup(...);
}
}
Examining the various posts, one way to get around this (as suggested in the post) is to configure the aspect in the XML configuration file and use the factory-method ="aspectOf" and in the configuration inject the reference to the NameService bean as a property. Our whole project uses Annotation based injection (as stated earlier). Assuming I can still configure the above aspect in an XML configuration file, how can I get the reference NameService bean Id so that I can add it to the configuration. I also saw a post related to using Configurable annotation but I assume that is for objects created outside the Spring IOC.
Currently, the aspects are woven using Aspectj compile option in pom.xml. Our root-context.xml contains the entry context:annotation-config and the aspect is injected into Spring IOC because component-scan is turned on for the folder where the aspect resides. Any help will be appreciated
This is well common error when use aspects in spring, you should add
<context:spring-configured/>
and
<aop:aspectj-autoproxy />
also add
#Configurable
#Aspect
public class Enable
To your appContext.xml
aspectOf is another style to do the above but I prefer use the nature of context.
It might be too late to answer this question. But i have come across the same situation and i fixed it as below.
1) Have a setter and getter for "NameService" in your aspect class.
2) Mark "NameService" with #Component ("nameService")
3) Configure "nameService" in xml configuration using setter injection.
4) Re-Start your server after making changes.
This should resolve the problem of getting null for "NameService" in aspect.
As in the title above, I am confused about pros cons between injecting applicationContext by directly #Autowired annnotation or implementing ApplicationContextAware interface in a singleton spring bean.
Which one do you prefer in which cases and why? Thanks.
Actually, both are bad. Both of them tie your application to the Spring framework, thus inverting the whole inversion-of-control concept. In an ideal world, your application should not be aware of being managed by an ApplicationContext at all.
Once you have chosen to violate this principle, it doesn't really matter how you do it. ApplicationContextAware is the legacy version that has been around at least since Version 2.0. #Autowired is a newer mechanism but they work in pretty much the same way. I'd probably go with ApplicationContextAware, because it semantically makes clear what it is about.
As #Sean Patrick Floyd says, the need of ApplicationContext is often due to a bad design. But sometimes you have no other option. In those cases I prefer the use of #Autowired because is the way I inject all other properties. So, if I use #Autowired for injecting MyRepository, why can't I use it for ApplicationContext or any other Spring bean?
I use Spring interfaces only for those things I can't do with annotations, for example BeanNameAware.
If you need to get a prototype in a singleton then you can use method injection. Basically, you create an abstract method that returns the object you need and spring will return the prototype everytime you call that method. You define the "lookup-method" in your spring config. Here are some links:
http://docs.spring.io/spring/docs/1.2.9/reference/beans.html#beans-factory-method-injection
http://java.dzone.com/articles/method-injection-spring
Since you are not extending any of the spring classes your application is always separated from the framework. Most of the cases you will not wanted to inject the ApplicationContext as it, but will need to inject the beans defined in the ApplicationContext.
The best case is always to stick to the bare minimum, until and unless you have any specific requirement and this is very simple with spring.
So either,
Annotate your beans and scan them in application context, then use #Autowire to wire them up.
Use application context to wire your bean expediencies(old xml style configs). You can use #Autowire with this approach also.
When you want to control the bean life cycle, you can read the API and customize it, but most of the time these general settings will do the job.
Here are some examples.
Spring Auto-Wiring Beans with #Autowired annotation
Spring Auto-Wiring Beans XML Style
Spring IoC container API Docs
There is no need to use ApplicationContext at all.
ObjectFactory
If you need to use prototype scoped beans in a singleton bean, inject an org.springframework.beans.factory.ObjectFactory.
For example using constructor injection:
#Service
class MyClass {
private ObjectFactory<MyDependency> myDependencyFactory;
public MyClass(ObjectFactory<MyDependency> prototypeFactory) {
myDependencyFactory = prototypeFactory;
}
}
Why
Now what's the benefit over using ApplicationContext ?
You can substitute this dependency (e.g. in a test) by simply passing a lambda (since ObjectFactory is a #FunctionalInterface) that returns a stubbed version of it.
While it is possible to stub the ApplicationContext, it is not clear in that case which beans will be looked up and need to be stubbed.
This is a question to understand spring internals. There are a couple of workarounds suggested for self injection of a bean in spring because #Autowired doesn't work. Here are few threads. I would like to know the reason why and how does self injection work technically with #Resource annotation?
#Service(value = "someService")
public class UserService implements Service{
#Resource(name = "someService")
private Service self;
}
Any links to the spring source code would be appreciated. Thanks.
From another thread I got a response which seems fairly ok. Basically it states that spring specially adds defensive checks for handling #Autowired beans but #Resource beans bypass it and hence it works.
I don't know how exactly spring handles it, but here are a few options (the CDI specification uses these for example):
incomplete instances. When beans are instantiated and put in the context, their status is set as 'incomplete' - that is, their instance exists but their dependencies are not injected. Thus, first beans are instantiated, put in the context, and on the next stage their dependencies are injected. This makes the above case trivial - the container first create the instance and then, for each injection point, gets the desired bean from the context - itself, in this case
proxies. A proxy is created for each bean, so that it has beans without actually having instantiated the beans. It creates the proxies (by interface/concrete class), injects them into one another, and passes proxies around when needed. Finally each proxy gets its actual bean. This is perhaps not the case above, because this is used by CDI to handle circular constructor injection.