Programmatic run-time injection/auto-wiring in quarkus - java

I am looking for a a way to do runtime injection of a bean in Quarkus. I realize this might be a bit on an unorthodox approach for quarkus, and something on an anti-pattern, so no need to point that out, I am fully aware :)
What I am looking for is a way to construct a bean during runtime, and having any annotated properties injected from the Quarkus context.
In Spring Boot I would get the application context by having a bean initialized normally by spring boot, using the ApplicationContextAware interface to inject the application context. I would then use that as a factory by calling ApplicationContext.getAutowireCapableBeanFactory() to get the auto-wire factory and using the autowireBean method on the factory to autowire my beans during runtime. I am wondering if something similar is possible in Quarkus?

This is similar to this question.
How to programmatically inject a Java CDI managed bean into a local variable in a (static) method
javax.enterprise.inject.spi.CDI.current().getBeanManager().select(C.class).get()
To make sure that the bean class is manged use the io.quarkus.arc.Unremovable annotation.

Related

Wrap blueprint bean into proxy proxy

I have worked with Spring and there is a nice feature
BeanPostProcessor where I can do with the bean whatever I want.
But now I am working with Apache aries blueprint (OSGI-based application) and wondering, is there anything similar to BeanPostProcessor in Blueprint? I need to wrap my bean in a proxy. Some interceptors, listeners, or anything that can help me work with beans? I need to add some functionalities to the beans during runtime (cache for example) and want to avoid changing the existing code.
Investigated the blueprint codebase, beans are created in BeanRecipe class in the blueprint, but I haven't found anything where I can inject my code for bean creation
I think proxy suits the best for such a purpose. Also, I am open to any suggestions from you. Thanks!

Spring handling bean colliision with library

Here's the situation: I have a RestTemplate bean defined in my main application (Spring boot 2). This application uses a library that also defines a RestTemplate bean to handle requests. I want to keep the main application's RestTemplate definition for my code, but I don't want the library to use my bean definition, since it will create a weird behaviour.
Is there a way to do that without using #Qualifier everywhere? Perhaps something like scoping my bean to my code only?

Can I inject properties to third-party beans?

Suppose I have classes, which were instantiated not by Spring. For example, they can be instantiated by deserializer or by JavaFX.
Can I code these classes in the same way I code Spring beans and inject properties into them later?
Actually, I would like a routine, which would scan class with reflection, find all #Autowired annotations in it and inject values from application context?
Will this happen, if I call applicationContext.getBeanFactory().registerSingleton("myName", myBean)? Note, that I would no limit myself with singletons.
If beans are not instantiated by Spring, then you cannot ask Spring to inject dependencies or advise them.
This is a common mistake I see Spring neophytes make. They call new to instantiate a bean with annotations and can't understand why their dependencies aren't injected.
Spring will handle all the beans you instantiate with the bean factory. You are on your own with all others created using new.

Where do those beans returned by Spring getBean method come from?

Could you please list all possible sources of getBean?
BTW, If I just write context.getBean(SomeInterface.class), can I get the implementation of the interface class?
They come from the Spring application context (which is what you are calling the getBean method on).
Spring has this concept of an application context, which is an object that contains things such as all the beans managed by Spring.
You put beans in the application context by configuring them in a Spring XML configuration file or by annotating classes with annotations such as #Component, #Service etc. and then letting Spring find them by scanning packages for those classes.
If you write context.getBean(SomeInterface.class) and there is a Spring bean that implements that interface, then that method call will return the bean that implements the interface.
These are basic concepts of the Spring framework. See chapter 5, The IoC Container in the Spring documentation for a detailed explanation of how it works.
If you go into the ApplicationContext class hierarchy, you will find that all spring Application Context file are child of org.springframework.core.io.DefaultResourceLoader class.
What DefaultResourceLoader does is it get the current thread context class loader(if none is provided). So we can understand that all application context file first load the classes defined. Application Context load all the beans defined in xml file, marked using #Bean annotation or other available spring annotations. Once the context scan through the annotation and/ or xml and load all the beans in the class loader. Context first create the dependencies and inject them in dependent.
To get context.getBean(SomeInterface.class), please refer below documentation.
http://docs.spring.io/spring/docs/3.0.x/api/org/springframework/context/support/AbstractApplicationContext.html#getBean(java.lang.Class)
As per my understanding of documentation, you shall get the bean if exact one implementation bean class is defined.

Spring, Multithreading and jms

Should the JmsTemplate bean be declared as a prototype bean or as a singleton? I think either option is reasonable and it seems to me it's mainly a question of how Spring implemented that bean but I keep finding conflicting reports about the use over the net.
JMSTemplate like most of the spring templates is thread safe after creation so you should leave it at scope singleton.
If the runnable is implemented as a inner class it can access the instance variables of the class in which you define it. This can be a spring bean with all the required dependencies (jmsTemplate etc) injected into it.

Categories