I have build a web application and scheduled cron job using cron4j. While executing the cron the run() method is calling and in the run() method all other bean objects are showing null. Hence, I am getting NullPointerException. Below is my sample code.
class Employee{
#autowired
IEmployeeService employeeService;
public void run() {
employeeService.getEmployeeDetails();
}
}
The above example employeeService object getting null and all other bean objects inside getEmployeeDetails(); are getting null and getJdbcTemplate() is also null.
How to initialize bean objects in spring while executing cron using cron4j.
You can use #BeanFactoryPostProcessor annotation to order creation of beans and create/run your job at the end of bean initialization.
The definition of BeanFactoryPostProcessor to bean (configuration metadata) processing. That is to say, the Spring IoC container allows configuration of BeanFactoryPostProcessor metadata in the container before the actual read instantiate any other bean, and may modify it. If you want, you can configure multiple BeanFactoryPostProcessor. You can control the BeanFactoryPostProcessor by setting the'order'attribute of the execution order.
From Spring documentation:
The next extension point that we will look at is the org.springframework.beans.factory.config.BeanFactoryPostProcessor. The semantics of this interface are similar to those of the BeanPostProcessor, with one major difference: BeanFactoryPostProcessor operates on the bean configuration metadata; that is, the Spring IoC container allows a BeanFactoryPostProcessor to read the configuration metadata and potentially change it before the container instantiates any beans other than BeanFactoryPostProcessors.
Please find more information on Spring docs: http://docs.spring.io/spring/docs/4.1.3.BUILD-SNAPSHOT/spring-framework-reference/htmlsingle/#beans-factory-extension-factory-postprocessors
Related
From the official documentation:
When registered by type, any existing single bean of a matching type (including subclasses) in the context will be replaced by the mock
What if the service under test is autowired in the constructor, though? E.g. in Kotlin (I suppose #MockkBean and #MockBean work the same regarding DI):
#RunWith(SpringRunner.class)
class ExampleTests #Autowired constructor(val userOfService: UserOfService) {
#MockkBean
private lateinit var service: ExampleService
...
}
I would expect this example to fail because in order to instantiate ExampleTests Spring has to first obtain a proper instance of UserOfService. That shouldn't be possible at that time, though, because there's no bean of type ExampleService in the application context yet.
Contrary to my expectation, this works. How is it possible?
Because you miss the other part from the documentation :
In either case, if no existing bean is defined a new one will be
added.
So #MockBean will also instantiate a bean automatically if that bean is not found in the spring context.
The sequence of actions are mainly as follows :
Start up the spring context which create all the spring BeanDefinition only that are registered in the spring context.
Process #MockBean which will replace the BeanDefinition in (1) or create a new BeanDefinition
Actually instantiate all the beans based on these BeanDefinition. It will handle which bean to be actually instantiated first and later.
Create a test instance (i.e ExampleTests) to execute its test methods. If any beans required to be auto-wired into the test instance are not created , it will fail.
So as long as you define UserOfService bean , ExampleTests can be instantiated as you are now using #MockBean on the ExampleService which means it must exist no matter you define it or not in the spring context for the test.
I am porting an existing JBOSS JEE application to Quarkus. I am using a number of HV custom validators that require injection.
For that purpose I've defined all custom validators that require injection as bean in my libraries like this:
#ApplicationScoped
public class SomeValidator implements ConstraintValidator<SomeValidation, AnObject> {
#Inject
public BeanUsingEntityManager bean;
Note: It is common code, so it should remain working on JBOSS as well
Next I defined a REST service. The REST service makes use of an application scoped bean like this.
#ApplicationScoped
public class ApplicationContext {
#PersistenceContext( unitName = "A" )
EntityManager em;
#Produces
#EnityManagerA // required qualifier to make datasource unique in JEE context (there are more)
public EntityManager produce() {
return em;
}
// NOTE: quarkus does not allow the #Produces on a field, which is allowed in JBOSS hence the method
#Produces
public BeanUsingEntityManager createBeanUsingEntityManager () {
// some logic that requires the entity manager.
}
}
Now the problem is simplified, but I keep on running into an error message.
Caused by: javax.enterprise.inject.CreationException: Synthetic bean instance for javax.persistence.EntityManager not initialized yet: javax_persistence_EntityManager_b60c51739990fc921960fc78caeb075a811a91a6
- a synthetic bean initialized during RUNTIME_INIT must not be accessed during STATIC_INIT
- RUNTIME_INIT build steps that require access to synthetic beans initialized during RUNTIME_INIT should consume the SyntheticBeansRuntimeInitBuildItem
at javax.persistence.EntityManager_e1903961aa3b05f292293ca76e991dd812f3e90e_Synthetic_Bean.create(EntityManager_e1903961aa3b05f292293ca76e991dd812f3e90e_Synthetic_Bean.zig:167)
at javax.persistence.EntityManager_e1903961aa3b05f292293ca76e991dd812f3e90e_Synthetic_Bean.create(EntityManager_e1903961aa3b05f292293ca76e991dd812f3e90e_Synthetic_Bean.zig:190)
at io.quarkus.arc.impl.AbstractSharedContext.createInstanceHandle(AbstractSharedContext.java:96)
at io.quarkus.arc.impl.AbstractSharedContext.access$000(AbstractSharedContext.java:14)
at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:29)
at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:26)
at io.quarkus.arc.impl.LazyValue.get(LazyValue.java:26)
at io.quarkus.arc.impl.ComputingCache.computeIfAbsent(ComputingCache.java:69)
at io.quarkus.arc.impl.AbstractSharedContext.get(AbstractSharedContext.java:26)
at javax.persistence.EntityManager_e1903961aa3b05f292293ca76e991dd812f3e90e_Synthetic_Bean.get(EntityManager_e1903961aa3b05f292293ca76e991dd812f3e90e_Synthetic_Bean.zig:222)
at javax.persistence.EntityManager_e1903961aa3b05f292293ca76e991dd812f3e90e_Synthetic_Bean.get(EntityManager_e1903961aa3b05f292293ca76e991dd812f3e90e_Synthetic_Bean.zig:238)
at nl.bro.gm.gmw.dispatch.resources.ApplicationContext_Bean.create(ApplicationContext_Bean.zig:131)
... 59 more
I'm new to Quarkus. So, not sure to how to handle this issue or even if I make the correct assumptions. I can imagine that Quarkus wants to give me a fresh entitymanager each request (which I understand), but that poses a problem for my application scoped beans.
What am I doing wrong here?
So, the full answer is that the EntityManager is created at the runtime init phase whereas the ValidatorFactory (and the ConstraintValidators) are created at static init time.
The Quarkus bootstrap goes static init -> runtime init.
So in your case, you can't access a #Singleton bean which uses the EntityManager during static init as it's not yet available.
Making your bean #ApplicationScoped will create a proxy and avoid this chicken and egg problem.
You will have only one BeanUsingEntityManager for your whole application.
The EntityManager is a bit different because we wrap it and you will get one new EntityManager/Session per transaction, which is what is expected as EntityManagers/Sessions are not thread safe.
I was trying to understand the difference between BeanFactoryPostProcessor and BeanPostProcessor.
I understood that BeanFactoryPostProcessor operates on bean definition i.e. before the bean instance is getting created it gets executed and BeanPostProcessor gets executed after bean is instantiated and lifecycle events are called.
Does this mean BeanFactoryPostProcessor is not a part of spring lifecycle events as it's called before instantiation while BeanPostProcessor is the part of Spring lifecycle events? Kindly verify if my understanding is right.
BeanFactoryPostProcessor is an interface and beans that implement it are actually beans that undergo the Spring lifecycle (Example below) but these beans don't take part of the other declared beans' lifecycle.
public class CustomBeanFactory implements BeanFactoryPostProcessor {
#Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
for (String beanName : beanFactory.getBeanDefinitionNames()) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
// Manipulate the beanDefiniton or whatever you need to do
}
}
}
The differences about BeanFactoryPostProcessor and BeanPostProcessor:
A bean implementing BeanFactoryPostProcessor is called when all bean definitions will have been loaded, but no beans will have been instantiated yet. This allows for overriding or adding properties even to eager-initializing beans. This will let you have access to all the beans that you have defined in XML or that are annotated (scanned via component-scan).
A bean implementing BeanPostProcessor operate on bean (or object) instances which means that when the Spring IoC container instantiates a bean instance then BeanPostProcessor interfaces do their work.
BeanFactoryPostProcessor implementations are "called" during startup of the Spring context after all bean definitions will have been loaded while BeanPostProcessor are "called" when the Spring IoC container instantiates a bean (i.e. during the startup for all the singleton and on demand for the proptotypes one)
Here is a flow diagram that might help to understand the spring bean initialisation life cycle.
As we can see, the implementation of theBeanFactoryPostProcessor is executed before any spring bean instantiation, contrary to the BeanPostprocessor, where the implemented method will be executed only when the bean is instantiated.
The source image is from the Spring 5 Design Patterns Book.
I pick the explanation from the book:
After loading the bean definitions from all styles of configurations,
BeanFactoryPostProcessor comes into the picture to modify the
definition of some beans, and then the container instantiates the
beans. Finally, BeanPostProcessor works on the beans, and it can
modify and change the bean object. This is the initialization phase.
Bean Factory Post Procesor (BFPP):
Used when we want to override XML / annotations, because Spring reads XML / annotations to create the beans. If you want to provide a different configuration to Spring during creation (at run time), then you need to use BFPP. Creating the internal dependency graph is a one time process.
Bean Post Processor (BPP):
The above step happened only once. It's like creating the "menu" of beans. After creating the bean, if you want to change the bean properties, you can't make any changes to the XML / annotations. Instead, you can use the BPP for bean configuration change after creation. The BPP has 2 execution areas, one before #postconstruct and one after #postconstruct.
Real Time Example:
You want to place an online food order from Zomato. While ordering online, you give a list of food (XML/annotations) to the restaurant. But, just before the restaurant starts making the food, you call them and ask them to change the dish (BFPP). Now the food is ready to be delivered and you've received it (Bean is created). But you want to make some modifications (like salt or chilly powder), and you can do this before tasting the food (because you know restaurants never put enough salt), or even after tasting the food (this is before and after #postconstruct). Once the taste is good, then the food is ready (the bean is ready to use).
The BeanFactoryPostProcessor executes before bean Object instantiation (ie at the time Applicationcontext container is initialized)
BeanPostprocessor is executed after the bean object is created, as it can be executed before init() and after init().
I am studying for the Spring Core certification an I have some doubts about how Spring handle the beans lifecycle and in particular about the bean post processor.
So I have this schema:
It is pretty clear for me what it means:
The following steps take place in the Load Bean Definitions phase:
The #Configuration classes are processed and/or #Components are
scanned for and/or XML files are parsed.
Bean definitions added to BeanFactory (each indexed under its id)
Special BeanFactoryPostProcessor beans invoked, it can modify the definition of any bean (for example for the property-placeholder values replacements).
Then the following steps take place in the beans creation phase:
Each bean is eagerly instantiated by default (created in right order with its dependencies injected).
After dependency injection each bean goes through a post-processing
phase in which further configuration and initialization may occur.
After post processing the bean is fully initialized and ready for use (tracked by its id until the context is destroyed)
Ok, this is pretty clear for me and I also know that there are two types of bean post processors which are:
Initializers: Initialize the bean if instructed (i.e. #PostConstruct).
and All the rest: that allow for additional configuration and that may run before or after the initialize step
And I post this slide:
So it is very clear for me what does the initializers bean post processors (they are the methods annotated with #PostContruct annotation and that are automatically called immediately after the setter methods (so after the dependency injection), and I know that I can use to perform some initialization batch (as populate a cache as in the previous example).
But what exactly represents the other bean post processor? What do we mean when we say that these steps are performed before or after the initialization phase?
So my beans are instantiated and its dependencies are injected, so then the initialization phase is completed (by the execution of a #PostContruct annotated method). What do we mean by saying that a Bean Post Processor is used before the initialization phase? It means that it happens before the #PostContruct annotated method execution? Does it means that it could happen before the dependency injection (before that the setter methods are called)?
And what exactly do we mean when we say that it is performed after the initialization step. It means that it happens after that the execution of a #PostContruct annotated method, or what?
I can easily figure into my head why I need a #PostContruct annotated method but I can't figure some typical example of the other kind of bean post processor, can you show me some typical example of when are used?
Spring doc explains the BPPs under Customizing beans using BeanPostProcessor. BPP beans are a special kind of beans that get created before any other beans and interact with newly created beans. With this construct, Spring gives you means to hook-up to and customize the lifecycle behavior simply by implementing a BeanPostProcessor yourself.
Having a custom BPP like
public class CustomBeanPostProcessor implements BeanPostProcessor {
public CustomBeanPostProcessor() {
System.out.println("0. Spring calls constructor");
}
#Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println(bean.getClass() + " " + beanName);
return bean;
}
#Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println(bean.getClass() + " " + beanName);
return bean;
}
}
would be called and print out the class and bean name for every created bean.
To undersand how the method fit the bean's lifecycle, and when exactly the method's get called check the docs
postProcessBeforeInitialization(Object bean, String beanName) Apply
this BeanPostProcessor to the given new bean instance before any bean
initialization callbacks (like InitializingBean's afterPropertiesSet
or a custom init-method).
postProcessAfterInitialization(Object bean, String beanName) Apply
this BeanPostProcessor to the given new bean instance after any bean
initialization callbacks (like InitializingBean's afterPropertiesSet
or a custom init-method).
The important bit is also that
The bean will already be populated with property values.
For what concerns the relation with the #PostConstruct note that this annotation is a convenient way of declaring a postProcessAfterInitialization method, and Spring becomes aware of it when you either by registerCommonAnnotationBeanPostProcessor or specify the <context:annotation-config /> in bean configuration file. Whether the #PostConstruct method will execute before or after any other postProcessAfterInitialization depends on the order property
You can configure multiple BeanPostProcessor instances, and you can
control the order in which these BeanPostProcessors execute by setting
the order property.
The typical example for a bean post processor is when you want to wrap the original bean in a proxy instance, e.g. when using the #Transactional annotation.
The bean post processor will be handed the original instance of the bean, it may call any methods on the target, but it also gets to return the actual bean instance that should be bound in the application context, which means that it can actually return any object it wants. The typical scenario when this is useful is when the bean post processor wraps the target in a proxy instance. All invocations on the bean bound in application context will pass through the proxy, and the proxy then gets to perform some magic before and/or after invocations on the target bean, e.g. AOP or transaction management.
The difference is BeanPostProcessor will hook into context initialization then call postProcessBeforeInitialization and postProcessAfterInitialization for all defined beans.
But #PostConstruct is just used for the specific class you want to customize bean creation after constructor or set method.
I have a bean with autowired beans.
So something like:
class A
{
#Autowired
B b;
#Autowired
C c;
void function()
{
// here I would like to do something when I an sure the wiring has been done
// being sure that I won't wait forever
...
Something has to exist, but I can't find it.
Thanks for your help!
You can annotate your 'function' method with #PostConstruct and specify <context:annotation-config/> in your spring config XML. Then, function will only be invoked after autowiring, so you could check in function whether your beans have been injected successfully.
A classic way to achieve this is to implement InitializingBean:
Interface to be implemented by beans that need to react once all their properties have been set by a BeanFactory: for example, to perform custom initialization, or merely to check that all mandatory properties have been set.
An alternative to implementing InitializingBean is specifying a custom init-method, for example in an XML bean definition. For a list of all bean lifecycle methods, see the BeanFactory javadocs.
I also suggest reading other answers:
How to call a method after bean initialization is complete?
What is the difference between BeanPostProcessor and init/destroy method in Spring?
If you are using default scope for beans that is singleton, then autowiring will always be done at the application startup only. If wiring for any field fails, then spring container will throw an exception and the application will not start properly. So, if the control of code is in your method , it means wiring has already been done.