Understanding spring singleton to load entities at startup - java

I want to implement a feature in which at deploy time, I should load list of objects from Database. The database already have respective implementaiton done which is being used on the fly.
Given that I am new to Spring, I am trying to understand different features of spring which i can leverage to implement this feature. If i wasn't using Spring, I would have
Created a Thread-Safe Singleton Class
Load that class at application load time by servlet life-cycle
Load everything in that Singleton Class and override existing db class to check this singleton class before issuing query. This way a query will be issued only if this class hasn't loaded for some reason.
Now, In spring, I am so confuse. I have been reaidng different articles and trying to find some pointers. First of all, shall i use #Component to make the class singleton ? Would spring take care of thread safety?
Secondly, Would this class be a Service class for spring ? Do i have to annotate it with #Service ?
Third, shall i use #PostConstruct to load this class at startup ? Or there are other better options ?

Here are the answers to your questions:
First of all, shall i use #Component to make the class singleton? Would spring take care of thread safety?
#Component is used for Component Scaning in XML based Spring Configuration to create the Spring Beans. A Bean will create a Singleton Instance of any Class.
Secondly, Would this class be a Service class for spring? Do I have to annotate it with #Service?
#Service is nothing but a Specialization of #Component. It's completely fine if you continue to use #Service or #Repository or replace them with #Component.
Third, shall I use #PostConstruct to load this class at startup? Or there are other better options?
#PostConstruct will run only once after the bean creation. It can be used if you want to load the data from DB to your cache etc. when your application starts for the first time.

Related

Programmatically create spring beans for each bean/configuration/... of a given type

I would like to create programmatically a bunch of different beans for each bean (or configuration or similar) extending a given base class.
What makes it more difficult is, that the beans should be already available at the phase the autowiring of other beans takes place.
Is the some kind of spring base class or interface (something like BeanPostProcessor) I could implement to achive that?
Use case is similar to create a bean for each data source in context.

Use class annotation to run on class initialization with Spring AOP

Is it possible to create a Java aspect that runs on class initialization using Spring AOP?
We have an annotation that will be used in several places, and in order to make use of the annotation we need some boilerplate code that needs to run every second (using #Scheduled). We're hoping to move that boilerplate code to another class-level annotation to make it easier to reuse.
As far as I understand, it's not possible to implement such a class-level annotation using Spring AOP since it only supports method execution (https://www.baeldung.com/spring-aop-vs-aspectj#4-joinpoints). Is there any workaround to achieve what we're hoping for? I'm aware we could use AspectJ instead of Spring AOP, but I'm reluctant to do that because it's complex to use.
Code snipped:
#Scheduled(fixedDelayString = "${app.pollable-consumer.time-interval}")
public void pollForDeletionRequest() {
log.trace("Polling for new messages");
cleanupInput.poll(cleanupSubmissionService::submitDeletion);
}
Thanks for your help.
Update: The annotation needs to be added to a library to enable it to be shared by different microservices.
We think that writing a new class-level annotation might help. It would run on class initialization, find all methods that are annotated with #PollableStreamListener, and schedule the polling to happen for each of the Kafka topics.
To slightly adjust the terminology and shift the focus, is it acceptable to bind the creation of such a construction to Spring's Application Context initialization? If so, you could create a Bean Factory Post Processor that would have been triggered for each #PollableStreamListener.
In a nutshell, BFPP runs before spring creates the beans during the application context initialization. This mechanism allows to "dynamically" create beans that in a runtime will be indistinguishable from those created by spring in a regular way, a kind of hook to the spring initialization lifecycle that you can use here.
So this BFPP and introspect the methods of your interest. Then based on the information found in the annotations / configuration This BFPP could register a Bean Definition per scheduled job of the bean (a class with all the required parameters that you could prepare as a part of the infrastructure). Then spring will read this bean definition and create the beans out of this bean definition as it usually does.
Here you can find an example of how to use this BFPP and more specifically its registerBeanDefintion method.

Spring 4 Dynamic Bean Creation

Maybe I'm not using the right terminology and that's why i can't find an answer, but I want to know how can I take information from a database to create beans that I can inject into the application?
Here's an example, rather than having this coded in a configuration file, I would like to possibly loop some values stored in a database and build these beans based on that:
#Bean
public CronTriggerFactoryBean cronTriggerFactoryBean() {
CronTriggerFactoryBean factory = new CronTriggerFactoryBean();
factory.setJobDetail(jobDetailFactoryBean().getObject());
factory.setStartDelay(3000);
factory.setCronExpression("0 0/2 * 1/1 * ? *");
return factory;
}
How can I build beans like this and have them become a part of the application?
There are probably multiple ways how to achieve that, but all of them are pretty complex with a lots of pitfalls. I would say that in your example you should not create triggers as separate beans but rather have a single service to manage your schedules (and leave it out of Spring).
The thing with Spring is, that it is not designed to act as a dynamic container (like OSGi for example). This means that for example #Autowired dependencies are initialized during context startup and stays the same till the application context is destroyed.
However it is possible to construct bean definitions on the fly during initialization. Best place would be BeanFactoryPostProcessor. But this would be called during context initialization. This means you will have no other beans available (like EntityManager, DataSource, ...).
Another possibility is to somehow take advantage of context hierarchy. You can create and destroy application contexts on-the-fly. However implementing that would require deeper knowledge of Spring's internals.
Question for others: not sure if it is possible to reference initialized beans from parent context during child context initialization.
After you load the necessary bean properties from Database , use BeanDefinitionBuilder. You can refer this link

Declare my own annotaion

As you know when I want to inject a class to my class's property in spring framework I do something like this:
Class sample {
#Autowired
MyService service;
}
or use #Resource or #Named or what else.
but now I wonder that if possible I declare my own annotation like #MyInjection to do this stuff and besides do something more.
for example, instead of searching the application context and find proper bean to inject, create a class and inject this created bean to property of class.
Thanks.
An annotation is just basically data about data. So if you want something to handle your annotation you have to write a custom annotation processor.
I suggest you should look into Spring's AOP features for more details:
Aspect Oriented Programming with Spring
With AOP you basically create an annotation (in your case) then you configure Spring to do something when it bumps into your annotation (Spring uses regexps for this if I remember it right). This is called a Pointcut. Then if Spring finds a match it runs your custom code which can be basically anything.
I think what you want could be achieved by using Spring's factory method, which gets called when Spring is about to resolve some dependency. See example Hope this helps.

Alternative to Spring's #Configurable for performance reasons?

I am using #Configurable beans for non-managed spring instances in a section of code that must be highly performant. We are using a lot of non-managed beans with the new operator, and in our profiling we have noticed that the use of the #Configurable annotation is slowing things down quite a bit.
Just for this specific section, we would like a faster way of pulling beans from the context (just a direct applicationContext.getBean()). I know we give up IoC doing this, but this is a special scenario and not a normal pattern.
We are using CTW for the weaving, but I wanted to know what mechanism spring is using behind the scenes to get the application context so we can simply grab it and use getBean? A static application context? Is it stored in threadlocal somewhere?
Aspects are singletons managed by AspectJ. When you put an aspect in your Spring configuration file Spring doesn't actually create the aspect. Instead it obtains a reference to the aspect using aspectOf().
This means that (at compile time when you do your weaving) your #Configurable annotation gets hooked into the singleton AnnotationBeanConfigurerAspect. Then when you load your application context, Spring obtains a reference to that same singleton aspect and calls the setBeanFactory() method on the aspect (since it implements BeanFactoryAware).
This magic can lead to trouble of course. If you had two application contexts then the second would overwrite the configuration of the first which can be terribly confusing.
To answer your question directly this means that all you have to do is create a new aspect that implements BeanFactoryAware (here is the code for AnnotationBeanConfigurerAspect which you can use as an example) and then "instantiate" that same aspect in your spring configuration file and your aspect will now have access to the bean factory.
If you're going for performance then please note that the above is not much cleaner than creating a static reference to the BeanFactory and instantiating that when you start your application so you might as well do the static reference as it is simpler.

Categories