Spring3 deserialization - singleton injection - spring

i am developing a Webapplication with JSF2 and Spring3 and have a problem with deserialization.
I have some session-scoped beans defined like so:
#Controller(value = "admin")
#Scope(value = "session")
public class AdminBean implements Serializable {
...
also i have some singletons defined like so:
#Repository
public class Repo {
Singletons are injected into the session-beans like this
#Resource
private transient Repo repo;
After i added transient, my problems with serialization/deserialization went away. But now i have the problem that after deserialzing the dependencies (repo in this case) are null. I searched a lot on this problem and found some workarounds, but i still wonder what the best solution for this problem is?
It seems to me that using application-scoped beans in session-beans is a quite common case, isn't there a clean solution for this? I came arround a solution with #Configurable, but do i really need some load-time-weaving stuff? The targets of the injection are already spring-managed, so it doesn't make sense to me..
Please enlight me
update 2 years later: You CAN transparently inject session-scoped beans into application-scoped-beans (might not be a good idea in most cases though). I just had to set the proxyMode on #Scope accordingly.

Try getting AutowireCapableBeanFactory through applicationContext.getAutowireCapableBeanFactory() and there are some methods like autowireBeanProperties, autowireBean and configureBean that should be able to reconfigure your ban after deserialization. Choose a method best for you (one of them triggers post processing, others not etc..)
Second idea is to wrap Repo in a proxy, that is serializable. It'll serialize with AdminBean and deserialize. This proxy should hold 'real' transient reference and if it gets null after deserialization, it should lookup it from the Application Context.
I heard that Spring 3 automaticaly wraps beans with such a proxy, but I've never managed to make it work.

I faced similar problem using #ViewScoped of JSF where backing bean has to serializable which in turn wants all dependencies to be serializable, which in all scenarios is not possible to get all. As #Peter mentioned about Spring 3 have a look at link # stackoverflow discussing same here. I used transient for some dependencies(Spring) and for deserialization process I hooked bean to
private void writeObject(java.io.ObjectOutputStream stream)
and private void readObject(java.io.ObjectInputStream stream)
in view scoped bean and tweaked them to get proper reference.

Related

IntelliJ can't find Spring bean from Kotlin object

I have a Spring Boot 2 + Kotlin application opened with IntelliJ 2019.1.
In this application I annotate some Kotlin objects with #Component. Example:
#Component
object MyObject: MyInterface {
// code
}
I have many different implementation of MyInterface (all with Kotlin objects) and I want to inject all of them in a list in another bean. Example:
#Component
class MyComponent #Autowired constructor(private val objects: List<MyInterface>) {
// code
}
The code runs correctly (the beans are inject in the list objects) but IntelliJ shows an error saying:
Could not autowire. No beans of '? extends MyInterface' or 'List<? extends MyInterface>' types found.
If I change 'object' to 'class' at 'MyObject', the error disappears.
My questions are:
Is it a problem with IntelliJ?
Is it not recommended to annotate Kotlin objects with #Component?
For information, as a possible workaround while the ticket created by Николай in this answer is not treated, I'm ignoring the error/warning only where I need with #Suppress("SpringJavaInjectionPointsAutowiringInspection"). Example:
#Suppress("SpringJavaInjectionPointsAutowiringInspection")
#Autowired
private lateinit var kotlinObjectBeans: List<MyInterface>
I hope it can help others that don't want to disable this check elsewhere.
I would recommend not to use kotlin objects with #Component or any other bean annotation.
There are two aspects and heaving a mix of them leads to lots of problems:
It might be several ApplicationContext instances in your application.
Kotlin object is related to a specific ClassLoader
It is a little bit strange to use Kotlin objects as #Component-s, because if your class knows that it will be used inside Spring-container you'll get more flexibility if you delegate to Spring the decision should this class be a singleton or not and all the other lifecycle management.
But practically I don't see any reason why it could be "not recommended" if you know what you are doing, and aware of probably bugs if your object become stateful.
So I think IDEA should support your case, and I've filled up a ticket IDEA-211826

Injected bean reset to NULL in the Aspect

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.

injecting spring beans into non-singleton classes

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.

Best Practise of injecting applicationContext in Spring3

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.

How does spring self injection works with #Resource?

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.

Resources