Declare my own annotaion - java

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.

Related

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.

Understanding spring singleton to load entities at startup

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.

Beans inside beans in SpringFramework?

There are some situations, where beans can be regarded as entities, similar to bean containers or configurations.
For example, GUI window can contain some controls. Here, both windows and it's controls are beans.
Does SpringFramework provide some specific patterns to implement this situation? For example, may be it is ok to implement BeanFactory or use #Component annotation for this?
Or the main guidance is still initialize everything from separate configuation and not mix it with real objects?
I cannot get your point clearly but what I understood is you are trying to have a bean inside a bean. If I understood correctly the you can use the annotation #Bean over a component inside any bean class which is decorated with any of the following annotation - #Controller, #RestController, #Configuration, #Repository, #Service, #Component.
A method onto which you decorate #Bean should return an object that can qualify to register as a bean.
Now you can inject (using #Autowired) this registered bean.

Writing a custom Spring #Cacheable annotation

I'm currently writing a custom #Cacheable annotation that will take additonal meta-data attributes in addition to those that Spring's #Cacheable provides. However, Spring would need to know how to parse this new annotation. My understanding is that I'd need to extend and override AnnotationCacheOperationSource's determineCacheOperations() so that the new annotation can be parsed with an appropriate CacheableOperation class initialized from it. Is this the correct way to proceed?
Regards,
Steve
Depends.
As per AnnotationCacheOperationSource javadoc,
This class reads Spring's Cacheable, CachePut and CacheEvict
annotations and exposes corresponding caching operation definition to
Spring's cache infrastructure. This class may also serve as base class
for a custom CacheOperationSource.
So if you're asking for yes/no answer if you can extend that class for an extended behaviour of CacheOperationSource, the answer is yes.
However, what determineCacheOperations() method does is that it uses all the available CacheAnnotationParsers. The only default CacheAnnotationParser is SpringCacheAnnotationParser. If you have a custom one, just have another class implementing CacheAnnotationParser for your annotation. Spring should then use it automatically. You can take a look at the SpringCacheAnnotationParser source code to see how they do it.
Edit: ok, I was wrong in that this would happen automatically. My next suggestion is to
implement the interface CacheAnnotationParser, like you apparently already did
extend AnnotationCacheOperationSource so that you put your own CacheAnnotationParser in addition to Spring one in the internal parsers collection
define your custom AnnotationCacheOperationSource to use the same id as Spring one does, so it will override Spring internal. If id matches, it should override Spring one cleanly. This would be something like:
<bean id="annotationCacheOperationSource"
class="com.company.YourCustomAnnotationCacheOperationSource" />

Adding behaviour using Spring

I have a bunch of projects which declare some spring bean files. I would like to write a "library" which supplies a utility which takes some bean names and adds some behaviour "around" the objects (example: Call Counting, Monitoring, Logging etc)
One obvious way for doing this would be to add some AspectJ annotations in the spring xml files in the projects but I would like the "utility" to search for some beans and add behaviour to them (This way the projects themselves are not aware of the utility).
The utility will be declared in the spring xml file somewhere so it has access to the ApplicationContext as it could implement ApplicationContextAware interface however I am keen on exploring how one would go about modifying behaviour of another bean in the app context programmatically. ex, something like find a bean of id "OrderService", create an aspected bean with some monitoring/call counting etc around all methods and replace that bean in the application context for "OrderService"
I know there are disadvantages with this approach but what I am after is "IS it possible to do this? And if yes how?"
If you don't want to use AOP, you can achieve this using a BeanPostProcessor. The Spring documentation states:
The BeanPostProcessor interface defines callback methods that you can
implement to provide your own (or override the container's default)
instantiation logic, dependency-resolution logic, and so forth. If you
want to implement some custom logic after the Spring container
finishes instantiating, configuring, and otherwise initializing a
bean, you can plug in one or more BeanPostProcessor implementations.
So you may create and register a BeanPostProcessor and implement the postProcessAfterInitialization(Object bean, String beanName) method to modify the methods you want to customize. Here is an example.
(But I would still recommend that you do this with AOP as this is the classical use case for it and it's much easier and more declarative. With the bean() pointcut, you can even advise beans with names matching a certain pattern.)
You can create your own BeanPostProcessor. You just have two declare it in applicationContext.xml and it will be called for each bean during initialization of beans (in fact, just before or just after). In each call you get a the actual object and its name. There, you can, for example, wrap that object depending on its name or type.

Categories