Why do we use #Autowire - spring

I am new to Spring so my understanding of it is very superficial, nevertheless, suppose we are looking at the following example:
class serviceImpl implements service{
#Autowired
private Mapper mapper;
public void executeService(){
mapper.executeSerice();
}
}
So, I am trying to build some service, which calls mapper from the persistence level. Mapper is an abstract class. So from my understanding, #Autowired will automatically injects one implementation of Mapper here.
Then my question is:
What if there are multiple implementations of Mapper? After some search, it seems that in this case one needs to use #Qualifier to designate which implementation we want to use.
Suppose we are using the implementation powerfulMapper, then we will need to use #Qualifier('powerfulMapper').
Then how is this different from just instantiating Mapper powerfulMapper here?

If you have only one Mapper , you only need #Autowired to inject. If there are more than one Mapper implementation registered as Spring bean , you have to use #Qualifier or #Resource to tell Spring which implementation you want to inject. See this for more details.
Then how is this different from just instantiating Mapper
powerfulMapper here?
The difference is that if a class is a Spring bean , we can apply some Spring feature on it such as :
Apply some AOP magic on it such as #Async , #Transactional , #PreAuthorize etc.
Think about the case that if a class has a lot of dependencies which in turn has a lot of dependencies, creating an instance of this class configuring with the whole dependency graph is not an enjoyable thing to do . Not to mention different dependency can has different requirements (e.g. one may needed to be instantiated as a singleton and will be shared to be used by different class while other may need to be in the prototype scope which different classes need a separate instance etc.)
Using #Autowired and let spring to configure such dependency graph is more easier than do it manually.
On the other hands , if the Mapper has very simple dependencies , only used internally inside ServiceImpl and you don't need any benefit provided by spring on it , you can simply instantiate it without declaring it as spring bean.

Dependency Injection (DI) is so that you avoid having a complicated tree of dependencies.
Imagen having a tree like structure where A instantiates class B and class B instantiates class C, then A instantiates D and D instantiates E.
A --> B ---> C
\
\--> D ---> E
This is all fine fine, until class E needs class C.
Then we need to re arrange everything and instantiate C higher up and pass it through class B and D down to both sides.
This is where DI comes into play.
We instead decide that A instantiates all classes
A --> B
--> C
--> D
--> E
So A is the owner of all classes, and he can then pass in any class to any class to meet whatever demand any class has.
This is what the Spring context does with the help of the #Autowire annotation. You declare for spring what class you want to be passed in the instantiated classes. Then Spring during startup, will instantiate all classes and then figure out what class should be fitted where (this is massive simplification). All classes will per default be instantiated as singletons (but this can be customised).
When spring instantiates you class it is called a spring managed bean. Spring manages the lifecycle of it. Not you, because you are not using new, the framework is.
During this process Spring does a number of checks and also instantiates in a specific order, configuration classes first, then #Bean annotated classes, and lastly #Component, #Service etc (overly simplifying this here), it will scan for what classes that should be instantiated, it will decide upon an order in which should be instantiated first, then which classes should be #Autowired into which classes. There are a number of help annotations that will assist Spring during this phase.
#Qualifier is one, you basically name a class, then you can tell spring where you want it #Autowired.
It's very useful if you have two singletons configured differently but they have the same name.

As you said, if you want different implementations you need to use #Qualifier("powerfulMapper") etc.
Lets suppose you have two different implementations one use #Qualifier("powerfulMapper") and the other is #Qualifier("notAPowerfulMapper").
Then while you autowire you also need to specify which one you need to inject like
#Autowired
#Qualifier("powerfulMapper")
private Mapper mapper;

Related

Is it still loose coupling if we use #qualifier

we use interface for autowiring service into controller
this is for loose coupling , coz the interface can hold object of any of its implementations. so no need to write the implementation name and create tight coupling.
however when we have more than one implementations for an interface, we write the #qualifier .
my question is if we have to write qualifier to tell which implementation needs to be injected, then should we still call it loose coupling??
class ServiceInterface {
interfaceMethod();
}
implementation 1:
#component("service1")
class ServiceImpl1 implements ServiceInterface {
interfacemethod(){
}
}
implementation 2:
#component("service2")
class ServiceImpl2 implements ServiceInterface {
interfaceMethod(){
}
now only instead of directly creating Object of ServiceImpl1() using new
ServiceImpl1 obj = new ServiceImpl1();
we write in
class Controller {
#autowired
#qualifier("service1")
ServiceInterface se;
sc.interfaceMethod();
}
Partially yes, because the component that uses the injected qualified bean still didn't create it or handle its lifecycle.
But indeed using #Qualifier creates some sort of coupling. If you want to avoid this, consider making one of your ServiceInterface beans the primary implementation for the interface annotating its class with #Primary as follows:
#Component
#Primary
class ServiceImpl1 implements ServiceInterface {
interfacemethod(){
}
}
With this, every time you need a ServiceInterface implementation but you don't actually specify which one you want (using #Qualifier) the primary one is injected by Spring.
Even though you are using the #Qualifier annotation you are still using inversion of control to let the framework manage your dependencies.
Furthermore, lets say you wouldn't autowire this implementation but use 'new' to create your object.
When the implementation changes you would need to update all the places where this is created. However, with dependency injection you wouldn't need to do so. Therefore you still have the advantages of dependency injection with regards to loose coupling.
If you would like to have your implementation less coupled with your target class then you could do a few things
Use #Primary for a bean to determine the default implementation.
Autowire your implementations into a List<ServiceInterface>
Use Spring's ObjectFactory to determine which bean to use at runtime
Use Profiles to determine which bean to autowire

Factory design pattern and Spring

I am wondering what is the current best practice as to the use of factory pattern within the context of Spring framework in using dependency injection. My wonder arises about whether the factory pattern is still relevant nowadays in light of the use of Spring dependency injection. I did some searching and see some past discussion (Dependency Injection vs Factory Pattern) but seem there is different view.
I see in some real life project in using a Map to hold all the beans and rely on autowiring to create those beans. When the bean is needed, it get it via the map using the key.
public abstract class Service {
//some methods
}
#Component
public class serviceA extends Service {
//implementation
}
#Component
public class serviceB extends Service {
//implementation
}
Map<String, Service> services;
But I see there is some difference among the two approaches.
Using the above method, all beans are created on application start up and the creation of object is handled by the framework. It also implies there is only one bean for each type.
While for factory pattern, the factory class creates the object on request. And it can create a new object for each request.
I think a deeper question may be, when Spring framework is used in a project, should it be strived to not create any object inside a class, which means the factory pattern ( or any creational design patterns?) should not be used, as Spring is supposed to be the central handler of the objects dependency ?
The answer to this question can be really deep and broad, I'll try to provide some points that hopefully will help.
First off, spring stores its beans (singletons) in the ApplicationContext. Essentially this is the map you're talking about. In a nutshell, it allows getting the bean by name, type, etc.
ApplicationContext, while being a really important concept, is not the whole Spring, in fact Spring framework allows much more flexibility:
You say, using a map implies that all the beans will be created at the beginning of the application and there is one instance of the bean.
Spring has a concept of Lazy beans, basically supporting a concept of beans being actually created only when they're required for the first time, so Spring supports the "delayed" beans initialization
Spring also allows more than one instance of a bean per type. So this map is more "advanced". For example you can create more than one implementation of the interface and use declare both as beans. As long as you provide enough information about what bean should be injected to the class that might use them (for example with a help of qualifiers suppored in spring), you're good to go. In addition, there are features in spring IoC container that allow injecting all registered implementations of an interface into a list:
interface Foo {}
#Component
class FooImpl1 implements Foo {}
#Component
class FooImpl2 implements Foo {}
class Client {
#Autowired
List<Foo> allFoos;
}
Now you say:
While for factory pattern, the factory class creates the object on request. And it can create a new object for each request.
Actually Spring can create objects per request. Not all beans have to be singletons, in general spring has a concept of scopes for this purposes.
For example, scope prototype means that Spring will create a bean upon each usage. In particular one interesting usage that spring supports in variety of ways is Injecting prototype bean into singleton. Some solutions use exactly like a factory (read about annotation #Lookup others rely on auto-generated proxy in runtime (like javax.inject.Provider). Prototype scope beans are not held in the application context, so here again spring goes beyond a simple map abstraction.
Last feature that you haven't mentioned is that sometimes even for singletons the initialization can be a little bit more complicated then calling a constructor with Parameters. Spring can address that by using Java Configurations:
#Configuration
public class MyConfig {
public SomeComplicatedObject foo(#Value("...") config, Bar bar) {
SomeComplicatedObject obj = new SomeComplicatedObject() // lets pretend this object is from some thirdparty, it only has no-op constructor, and you can't place spring annotations on it (basically you can't change it):
obj.setConfig(config);
obj.setBar(bar);
return obj;
}
}
The method foo here initializes the object SomeComplicatedObject and returns it. This can be used instead of factories to integrate "legacy" code (well, java configurations go way beyond this, but its out of scope for this question).
So bottom line, you Spring as an IoC container can provide many different ways to deal with object creation, in particular it can do everything that factory design pattern offers.
Now, I would like to also refer to your last sentense:
I think a deeper question may be, when Spring framework is used in a project, should it be strived to not create any object inside a class, which means the factory pattern ( or any creational design patterns?) should not be used, as Spring is supposed to be the central handler of the objects dependency ?
Indeed you don't have to use Factory Pattern when using Spring, since (as I hopefully have convinced you) provides everything that factory can do and more.
Also I agree that spring is supposed to be the central handler of the objects dependency (unless there are also parts of the application which are written in a different manner so you have to support both :) )
I don't think we should avoid using "new" altogether, not everything should/can be a bean, but I do see (from my subjective experience, so this is arguable) that you use it much less leaving the creation of most of the objects to Spring.
Should we avoid a usage of any creation design pattern? I don't think so, sometimes you can opt for implementing "builder" design pattern for example, its also a creational pattern but spring doesn't provide a similar abstraction.
I think if your project uses Spring framework you should use it. Although it depends on your project design e.g. You may use creational patterns along side with Spring IoC. e.g when you have abstraction layers not framework dependant (agnostic code)
interface ServiceFactory {
Service create(String type);
}
#Component
class SpringServiceFactory implements ServiceFactory {
#Autowired private ApplicationContext context;
Service create(String type) {
return context.getBean(type)
}
}
I use Factory pattern as well when I refactor legacy not unit testable code which also uses Spring Framework in order to implement unit tests.
// legacy service impossible to mock
class LegacyApiClient implements Closeable {...}
#Component
class LegacyApiClientFactory {
LegacyApiClient create(String endpoint) {
return new LegacyApiClient(endpoint);
}
}
#Component
class OtherService {
private final String endpoint
private final LegacyApiClientFactory factory;
OtherService(#Value("${post.endpoint}") String endpoint,
LegacyApiClientFactory factory) {...}
void doCall {
try (LegacyApiClient client = factory.create(endpoint)) {
client.postSomething();
}
}
}
....
// a random unit test
LegacyApiClient client = mock(LegacyApiClient.class)
LegacyApiClientFactory factory = mock(LegacyApiClientFactory.class)
OtherService service = new OtherService("http://scxsc", factory);
when(factory.create(any())).thenReturn(client)
service.doCall()
....

How to register bean programatically in Quarkus?

I am trying to find a way how to programatically create bean in quarkus DI, but without success. Is it possible in this framework? It seems that BeanManager does not implement the needed method yet.
First, we should clarify what "programatically create bean" exactly means.
But first of all, we should define what "bean" means. In CDI, we talk about beans in two meanings:
Component metadata - this one describes the component attributes and how a component instance is created; the SPI is javax.enterprise.inject.spi.Bean
Component instance - the real instance used in application; in the spec we call it "contextual reference".
The metadata is usually derived from the application classes. Such metadata are "backed by a class". By "backed by a class" I mean all the kinds described in the spec. That is class beans, producer methods and producer fields.
Now, if you want to programatically obtain a component instance (option 2), you can:
Inject javax.enterprise.inject.Instance; see for example the Weld docs
Make use of CDI.current().select(Foo.class).get()
Make use of quarkus-specific Arc.container().instance(Foo.class).get()
However, if you want to add/register a component metadata that is not backed by a class (option 2), you need to add an extension that makes use of quarkus-specific SPIs, such as BeanRegistrar.
If you are looking for Quarkus equivalent of Spring #Configuration then you want "bean producer" (as mentioned in comments above)
Here is an example(koltin) of how to manually register a clock:
import java.time.Clock
import javax.enterprise.context.ApplicationScoped
import javax.enterprise.inject.Produces
#ApplicationScoped
class AppConfig {
#Produces
#ApplicationScoped
fun utcClock(): Clock {
return Clock.systemUTC()
}
}
#Produces is actually not required if method is already annotated with #ApplicationScoped
#ApplicationScoped at class level of AppConfig is also not required
Although, I find those extra annotations useful, especially if are used to Spring.
You can inject your beans using Instance:
#Inject
public TestExecutorService(final ManagedExecutor managedExecutor,
final Instance<YourTask> YourTask) {
this.managedExecutor = managedExecutor;
this.YourTask= YourTask;
}
And if you need to create more than one Instance you can use the managed executor:
tasks.forEach(task -> managedExecutor.submit(task::execute));
Keep in mind that depending on the way you start the bean you may need to destroy it and only the "creator class" has its reference, meaning you have to create and destroy the bean in the same classe (you can use something like events to handle that).
For more information please check: CDI Documentation

Inconvenient of #Value Annotation in Spring 3.0

I'm wondering if I add a #Value annotation on a property, the class who contains this property cannot be used by another one with a different value, Example :
MyClassUtil.java had
#Value("${some.value}")
private int _myProperty;
And of course there is one module.properties who contain :
some.value=10
Another class ClassA.java wants to use this class with value 10. Ok, no problem.
But another class ClassB.java wants to use this class but with another value : 20. I cannot do this if I'm not mistaken.
Because before #Value era, I could declare two beans in the moduleContext.xml without any problem.
So, is #Value pushes you to do some strong coupling ?
You are right that the annotation configuration can not be instance specific. It is important to understand the concept of bean definitions in bean factory.
Manual bean definition:
Single <bean> element in your XML config leads to a single bean definition. Multiple <bean> mean multiple definitions (regardless of a bean type).
Single #Bean method within #Configuration class leads to a single bean definition. Multiple #Bean methods mean multiple definitions (regardless of a bean type).
However when using component scan, classes annotated with #Component-like annotations are auto-registered as a single bean definition. There is no way you can register bean multiple times via component scan.
Similarly, annotation configurations (#Value, #Autowired, etc.) are type-wide. Your bean instances are always augmented and processed with the same effect (e.g. injecting the same value). There is no way you can alter annotation processing behaviour from instance to instance.
Is this tight coupling? It is not in its general understanding - bean factory (Spring) is still free to inject whatever it thinks is suitable. However it is more of a service lookup pattern. This simplifies your life when working with domain specific singletons. And most beans in an application context tend to be singletons, many of them domain specific (controllers, services, DAOs). Framework singletons (non-project specific reusable classes) should never use annotation based configuration - in this scope, it is an unwanted tight coupling.
If you need different bean instances, you should not use annotation configuration and define your beans manually.

Should I use dependency injection on these domain classes?

Do I use dependency injection in the following example:
#Scope("prototype")
#Component
public class Order{
#Autowired
public Order(User user,List<OrderItem> items,.......){
Now somewhere else:
#Component
public class PersistOrder{
#Autowired
Provider<Order> orderProvider;
public void prepareOrder() {
Order order = orderProvider.get();
AS JSR-330 states, the get() method of Provider returns a new instance of Order, but what objects are passed to the new order's constructor? As you can see the order has its own dependencies that has to be injected before the actual order object is retrieved to the method.
Without DI I simply create all neccessary arguments and pass them to the constructor of the new order. So should I use DI here?
EDIT:
This is what the code would seem without DI:
#Component
public class PersistOrder{
public void prepareOrder() {
User user=userDao.get(userId);
List<OrderItem> orderItems=orderItemDao.getAll(orderItemIds);
Order order = new SmartPhoneOrder(user,orderItems);
As you see I have the ids of user and order items and can get their instances from DAOs. Then I pass these instances to the constructor of a subclass of the Order to get an instance. The process seems very clear to me. I mean how can I do this work with DI so that my code enjoy decoupling between PersistOrder and Order classes? Or using DI in this example makes the logic more complex?
Without dependency injection, domain objects can be considered anaemic, and this is arguably an anti-pattern. You're losing many of the benefits of OO, by having data structures, without associated behaviors. For example, to evaluate Order.isValid() you may need to inject some dependency to perform the validation.
You can get dependency injection on classes outside the context of the Spring container by using:
#Configurable
You then declare the recipe for the bean as a protoype, and Spring will use AOP to swizzle the constructor and look up the required dependencies. . Even though its looking up the dependencies, the net effect for you is dependency injection, because you'd only have to change one line to inject something else that evaluates Order.isValid().
This way when you do new Order, or get it from you persistence factory, it already has the dependencies "injected".
To do this requires aspectJ weaving and not just Proxy/CGLib weaving, which is the default. You can use either runtime weaving with a Java agent or build-time weaving. . . I recommend the former for integration tests and the latter for deployment. . .
Service vs Domain Object:
Now that you have the option of rich domain objects the question becomes where to put stuff. Service vs Entity? My take is that the service should orchestrate a use-case specific process based on reusable domain objects. The service is your non-OO gateway for outside subscribers into you system.
. . Google Spring #Configurable for more information and tutorials on AspectJ-based dependency injection of domain classes.

Resources