Custom modification of new bean instances in Quarkus - spring

I need to scan new beans for the presence of an annotation when they are added to the application context. I need something like BeanPostProcessor from Spring.

Related

ApplicationContext - Need clarification

I am new to springs and have the following queries on ApplicationContext.
1.What does it mean to declare two instances of classPathXmlApplicationContext on a single beans.xml file?
2.How is a beanPostProcessor programmatically associated with a single ApplicationContext?
1.What does it mean to declare two instances of classPathXmlApplicationContext on a single beans.xml file?
This would result in two different Spring application context unaware of each other. If there are any beans that are defined as singleton, each application context will now have its own instances of singleton beans, which means two bean instances one for each application context.
2.How is a beanPostProcessor programmatically associated with a single ApplicationContext?
To register a BeanPostProcessor you can add that to the spring configuration(xml/annotation) as a normal bean and spring will detect that automatically during the container startup and will invoke its callback methods during bean creation.
If you want to do this programatically, you can use BeanFactoryPostProcessor and addBeanPostProcessor method

Inject properties into object which is not a spring managed bean

I have a spring application where in some cases I need to create an object at runtime, as opposed to a spring injected bean. This object should be created with properties that come from the application context however. If this object is not spring-injected, how can I still take advantage of IoC? Should I make these object properties static and inject them into a bean via non-static setters?
You can still inject properties for object which is not created by spring.
To do that you should use #Configurable annotation. And you should enable LoadTimeWeaving or CompileTimeWeaving. But I think that can be overkill for your situation.

Spring - what's a bean and what's not?

I'm new to Spring and I'm confused about something basic. Are the classes that are stereotyped (Service, Controller, Repository) treated as beans? I'm confused as to when you actually need to annotate/configure something as a bean and when you don't. Is it for the classes that aren't stereotyped?
Thanks!
From spring documentation:
In Spring, the objects that form the backbone of your application and
that are managed by the Spring IoC container are called beans. A bean
is an object that is instantiated, assembled, and otherwise managed by
a Spring IoC container. Otherwise, a bean is simply one of many
objects in your application. Beans, and the dependencies among them,
are reflected in the configuration metadata used by a container.
Service, Controller, Repository are managed by the Spring IoC container, so they are called beans. You annotate a class as #Serivice, #Controller, #Repository, or more in general #Component when you want spring to manage it: spring will manage the instance of annotated class in regard of the scope you select (not all these scope are always available):
singleton – Return a single bean instance per Spring IoC container
prototype – Return a new bean instance each time when requested
request – Return a single bean instance per HTTP request
session – Return a single bean instance per HTTP session
globalSession – Return a single bean instance per global HTTP
session

Getting Spring object instantiation right

I'm new to Spring and a little confused about how it works. I get that I can use the application context to instantiate beans and have them populated. However, is the idea that I should be able to just write Bean b = new Bean() and then have Spring to somehow automagically populate that Bean?
I'm experimenting with Spring in a web application, and as far as I can see I need to inject the ApplicationContext into, say, the servlets to be able to instantiate other beans (services, daos etc.) from there. It's a bit cumbersome, but probably works.
However, is Spring meant to be able to hook into any object instantiation which happens on classes defined as beans in applicationContext.xml?
Spring is an Inversion of Control container. A bean is an object whose life cycle is managed by Spring. If you want Spring to populate an object, it needs to go through Spring, ie. it needs to be bean.
is Spring meant to be able to hook into any object instantiation
which happens on classes defined as beans in applicationContext.xml?
Spring doesn't hook into anything. You configure your beans and the relationships between them with Spring and Spring handles creating the instances and linking them up.
For domain objects, Spring provides a solution via the #Configurable annotation: http://docs.spring.io/spring/docs/4.0.0.RELEASE/spring-framework-reference/htmlsingle/#aop-atconfigurable
It requires compile- or load-time-weaving and, thus, introduces some additional complexity but having the convenience of using the standard new Bean() syntax plus Spring's autowiring is worth it in my opinion.
Alternatively, you could define your domain objects as beans with prototype scope and use some factory to create them using the Spring ApplicationContext.getBean() method. With a scope of prototype a new instance will be returned every time and since you go through the ApplicationContext, Spring will do all the dependency injection magic as usual.
As for services and other beans with singleton scope, you would typically NOT retrieve them by first injecting the ApplicationContext and using it but instead you would inject them via either a constructor, setter or annotation-based strategy. The documentation covers that in detail: http://docs.spring.io/spring/docs/4.0.0.RELEASE/spring-framework-reference/htmlsingle/#beans-factory-collaborators

dynamically declare beans at runtime in Spring

I am wondering if the following is possible. For testing purposes, I wish for different mock classes to be declared in the application context for different tests. These are acceptance tests, using the Jersey REST client. Is there a way to dynamically declare a bean at runtime? Does Spring have an API to allow changes to the application context after the context has been loaded?
The common way to have different beans in the application context is using profiles. You can read about profiles in the following spring source posts:
http://blog.springsource.org/2011/02/14/spring-3-1-m1-introducing-profile
http://blog.springsource.org/2011/06/21/spring-3-1-m2-testing-with-configuration-classes-and-profiles/
About your first question, you can declare beans at runtime via BeanDefinitionRegistry.registerBeanDefinition() method, for example:
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(SomeClass.class);
builder.addPropertyReference("propertyName", "someBean"); // add dependency to other bean
builder.addPropertyValue("propertyName", someValue); // set property value
DefaultListableBeanFactory factory = (DefaultListableBeanFactory) context.getBeanFactory();
factory.registerBeanDefinition("beanName", builder.getBeanDefinition());
Is possible also to register a singleton bean instance (already configured) with
context.getBeanFactory().registerSingleton(beanName, singletonObject)
Finally, Spring don't provides a clear way to change a bean after refreshing the context, but the most common approachs are:
close and refresh again (obiously)
Use a proxy and swap the targetSource at runtime: see Replace spring bean in one context with mock version from another context (for an example).

Resources