Azure Springboot Function Is Only Initialized Once and Not Called Again
Spring is a powerful framework, but information technology requires some skill to utilize efficiently. When I started working with Spring a while ago (really Leap Boot to develop microservices) I encountered some challenges related to dependency injection and using the @Autowired annotation. In this blog I'll explain the issues and possible solutions. Practice note that since I exercise non have a long history with Bound, the provided solutions might not be the all-time ones.
Introduction @Autowired
In Jump 2.5 (2007), a new feature became available, namely the @Autowired notation. What this annotation basically does is provide an instance of a class when you request it in for example an example variable of another class. You can do things similar:
@Autowired MyClass myClass;
This causes myClass to automagically be assigned an example of MyClass if certain requirements are met.
How does it know which classes can provide instances? The Spring Framework does this by performing a scan of components when the application starts. In Jump Kick the @SpringBootApplication provides this functionality. You tin can use the @ComponentScan notation to tweak this behavior if yous demand to. Read more here.
The classes of which instances are acquired, also have to exist known to the Spring framework (to exist picked up by the ComponentScan) so they require some Jump annotation such as @Component, @Repository, @Service, @Controller, @Configuration. Leap manages the life-cycle of instances of those classes. They are known in the Bound context and can exist used for injection.
Society of execution
When a constructor of a form is called, the @Autowired example variables do not contain their values yet. If you are dependent on them for the execution of specific logic, I propose you use the @PostConstruct annotation. This annotation allows a specific method to be executed afterward construction of the instance and besides afterwards all the @Autowired instances accept been injected.
Multiple classes which fit the @Autowired neb
If y'all create an instance of a class implementing an interface and there are multiple classes implementing that interface, you tin can use different techniques to let it determine the correct i. Read here.
You tin indicate a @Primary candidate for @Autowired. This sets a default form to be wired. Another alternatives are to use @Resource, @Qualifier or @Inject. Read more here. @Autowired is Spring specific. The others are not.
Y'all can for example name a @Component like:
@Component("beanName1") public class MyClass1 implements InterfaceName { } @Component("beanName2") public class MyClass2 implements InterfaceName { } And use it in an @Autowired like
@Autowired @Qualifier("beanName1") InterfaceName myImpl; MyImpl will get an instance of MyClass1
When @Autowired doesn't work
There are several reasons @Autowired might not piece of work.
When a new instance is created not by Spring merely past for example manually calling a constructor, the instance of the class will not exist registered in the Jump context and thus not available for dependency injection. Likewise when you use @Autowired in the class of which you created a new instance, the Jump context volition non be known to it and thus almost likely this will also neglect.
Another reason can be that the form you want to use @Autowired in, is non picked up past the ComponentScan. This can basically be because of ii reasons.
- The parcel is exterior the ComponentScan search path. Move the parcel to a scanned location or configure the ComponentScan to fix this.
- The class in which you want to use @Autowired does not have a Bound annotation. Add together one of the following annotatons to the class: @Component, @Repository, @Service, @Controller, @Configuration. They take different behaviors so choose advisedly! Read more than here.
Instances created not by Bound
Autowired is absurd! It makes sure things very easy. Instances created not by Spring are a claiming and stand between you and @Autowired. How do you deal with this?
Do not create your ain instances; permit Spring handle it
If yous can practise this (refactor), it is the easiest way to go. If you lot need to deal with instances created non by Bound, there are some workarounds available beneath, but almost likely, they will have unexpected side-effects. It is piece of cake to add Spring annotations, have the class be picked up past the ComponentScan and permit instances be @Autowired when you need information technology. This avoids you having to create new instances regularly or having to forward them through a call stack.
Not like this
//Autowired annotations will not work within MyClass. Other classes who desire to utilise MyClass have to create their ain instances or y'all have to forward this one. public course MyClass { } public grade MyParentClass { MyClass myClass = new MyClass(); } Only like this
Below how y'all tin can refactor this in gild to Springify it.
//@Component makes sure it is picked up by the ComponentScan (if it is in the right bundle). This allows @Autowired to work in other classes for instances of this course @Component public class MyClass { } //@Service makes sure the @Autowired annotation is processed @Service public class MyParentClass { //myClass is assigned an case of MyClass @Autowired MyClass myClass; } Manually force Autowired to exist processed
If yous want to manually create a new instance and forcefulness the @Autowired annotation used inside it to exist processed, you lot can obtain the SpringApplicationContext (see here) and practice the following (from here):
B bean = new B(); AutowireCapableBeanFactory manufacturing plant = applicationContext.getAutowireCapableBeanFactory(); factory.autowireBean( bean ); factory.initializeBean( bean, "bean" );
initializeBean processes the PostConstruct note. At that place is some discussion though if this does not break the inversion of command principle. Read for case hither.
Manually add the bean to the Spring context
If you not only want the Autowired annotation to be candy inside the bean, only also make the new case available to be autowired to other instances, it needs to exist present in the SpringApplicationContext. You tin obtain the SpringApplicationContext by implementing ApplicationContextAware (come across here) and use that to annals the edible bean. A nice instance of such a 'dynamic Spring bean' can be found here and here. There are other flavors which provide pretty like functionality. For example here.
Source: https://technology.amis.nl/software-development/java/java-how-to-fix-spring-autowired-annotation-not-working-issues/
0 Response to "Azure Springboot Function Is Only Initialized Once and Not Called Again"
Postar um comentário