Spring #Predestroy method and context availability - spring

Do I correctly understand that when the #Predestroy method is invoked for a Spring component all other components (autowired dependencies) are still fully available in the context and not destroyed?
Thus can I invoke in the #Predestroy method other beans and not get exceptions?
I need #Predestroy to make some operations with DB through some autowired #Service bean.

Related

Fire CDI event AFTER bean creation via producer

I have a CDI producer method which creates an UserBean. The producer fires an UserBeanEvent. Other beans rely on that user bean and those beans may be used in the observer methods.
CDI again tries to create the user bean, the producer is invoked, the event is fired and so on - endless loop.
Is there any neat way to fire the event AFTER the producer completed and the bean was fully added to the bean store? I looked through the sources but I was not able to find anything.
I'm using WELD 2.3.5.final on WildFly 10.1
You need to detail several things, and one of the most important one is scope, and at what point is the bean needed?
Obviously if there is an observer method that listens to this bean event, and also needs a reference to this bean in the observer parameter, then you are definitely creating a cyclic dependency, which you cannot resolve, as the events in CDI are synchronous by default (And even if you use the fireAsync, there is no guarantee that by the time the event arrive, CDI has put the bean into proper context)
I would solve this problem by doing a method injection on an eargerly loaded bean such as ejbs Singleton or #ApplicationScoped with some kind of earger loading, and then fire the event from there.
Assuming that the bean is eargerly loaded:
public class EargerBean {
#Inject
private Event<BeanEvent> event;
#Inject
public void onInjected(Bean bean){
BeanEvent beanEvent ...;
event.fire(beanEvent);
}
}

Spring #PreDestroy method

I found out that #PreDestroy only work with singleton scoped bean. I was thinking what could go wrong if we use it with prototype scoped bean. Anything at all??? I dont think so. I think this is just not implemented in spring as they would have to keep the references to all the beans created. Tell me if i am wrong
Spring can only initialize/destroy beans it also controllers and basically prototype scoped beans aren't under the control of spring (after construction). It doesn't know when it is cleaned up, destroyed or what so ever. As such the #PreDestroy method isn't callable for prototype beans (as they do not have a clearly defined lifecycle like singletons or request scoped beans).
For "prototype" scoped beans, Spring does not call the #PreDestroy method.
Here is the answer from the Spring reference manual. Section 7.5.2
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-factory-scopes-prototype
In contrast to the other scopes, Spring does not manage the complete lifecycle of a
prototype bean: the container instantiates, configures, and otherwise assembles a
prototype object, and hands it to the client, with no further record of that prototype
instance.
Thus, although initialization lifecycle callback methods are called on all objects regardless of scope, in the case of prototypes, configured destruction lifecycle callbacks are not called. The client code must clean up prototype-scoped objects and release expensive resources that the prototype bean(s) are holding.
To get the Spring container to release resources held by prototype-scoped beans, try using a custom bean post-processor, which holds a reference to beans that need to be cleaned up.
The #PreDestroy annotation does not belong to Spring, it’s located in the jsr250-api library jar under javax.annotation package.
By default, Spring will not aware of the #PreDestroy annotation. To enable it, you have to either register CommonAnnotationBeanPostProcessor or specify the <context:annotation-config /> in bean XML configuration file.

spring access beans during context initialisation

I want to access the Spring Applciation Context , when the entityManagerFactory is getting initialised.
We can use ApplicationContextAware , but the entityManagerFactory gets instantiated before our ApplicationContextAware bean is initialised.
Share if anybody has done something like this .
You could subclass entitymanagerfactory and give it a constructor with ApplicationContext, and wire the context into the constructor.
Note that tampering with the applicationcontext while it's still being initialized is strongly discouraged.
Configure the bean to use ApplicationContextAware and then set the SessionFactory bean's depends-on attribute to the context aware bean. This should cause the bean to be created prior to the sessionFactory.

How does #SessionScoped work with EJB? Is CDI only for web-tier?

How is the session defined in #SessionScoped CDI bean?
Is this annotation valid only when called from Servlet container, where the session is well defined in form of HttpSession?
If not, than how an EJB with #Inject #SessionScoped MyBean myBean can know what the session really is? I mean, methods of this EJB could have been invoked by a standalone client, RESTful WS or by some other view.
What should happen in such case? Should the annotation have no meaning, should it inject fresh MyBean instance for each request or maybe it should retain the same instance across all requests?
Taken from the #SessionScoped specification
The session scope is active:
during the service() method of any servlet in the web application,
during the doFilter() method of any servlet filter and when the
container calls any HttpSessionListener, AsyncListener or
ServletRequestListener.
So in short, yes. It is bound to the HttpSession. Also:
The session context is shared between all servlet requests that occur
in the same HTTP session. The session context is destroyed when the
HTTPSession times out, after all HttpSessionListeners have been
called, and at the very end of any request in which invalidate() was
called, after all filters and ServletRequestListeners have been
called.

What does <tx:annotation-driven/> in Spring really do in the code level?

Does it set a flag in a bean ?
Does it load "special" bean which then looks for #Transactional ?
It scans all beans in the application context and creates AOP interceptor for those which are annotated.
This is done via the SpringTransactionAnnotationParser, which is used by TransactionInterceptor - the aformentioned interceptor.
Then whenever these beans are accessed, this advice is triggered and a transaction is started before the target method is executed, and committed after the execution.

Resources