Why to use #Autowired on class in Spring - spring

I read about the advantages of using Dependency for interface.
I understand the concept for interface - but why to use #Autowire on class? If we use Autowire on class I know in advance what is the implmeneted class and it's like a regular member of it (without the ability of get to this member)!
What am I missing?

1) Convenience - you do not need to take care for initializing your components, you save time on typing code and configuration files,
2) Forcing good practices - your components to be autowired must be written to be manageable by Spring and spring will take care about error checking for you and pop all errors. So your code will be organized in component collaborating way.
3) Autowiring will also reduce your effort when your classes/beans will grow and evolve.

If you use #Autowire and not call the constructor, you mark the class to be dynamically initialized by the Spring Container. This allows you to set class properties as defined in your spring configuration.

If we use Autowire on class I know in
advance what is the implmeneted class
and it's like a regular member of it
When you wire the dependency through XML instead of Annotations, you also know in advance in which class are you going to inject it.
But You still declare an Interface as dependency, so you can wire any Implementation of this interface at runtime.

Related

Why do we use #Autowire

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;

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

Use of #Scope annotation with Spring Controller

I am working on a project which is based on Struts 1.x, converting it to Spring 4. I have visited many tutorial sites and read Spring 4 tutorials but no one used #Scope annotation with #Controller in tutorial application. My Question is :
1) Is it compulsory to use #Scope attribute?
2) What if we do not use?
3) Is it good practice to use #Scope with #Controller?
We have also reading a property file at server start up and storing it into Property class. I am reading some property in DAOImpl class(Annotated as #Repository). If I use #Scope attribute with both Controller and Repository then it return value otherwise it return NullPointerException. Why is this behavior?
1) Is it compulsory to use #Scope attribute?
No. If you want the default ("singleton") then you don't need to specify.
2) What if we do not use?
Then your application will only create one instance of the bean.
3) Is it good practice to use #Scope with #Controller?
No. It does not make sense for an application to have more than one instance of a controller class (or a repository). If you have a need to use both annotations together, then you are not modelling your classes very well.
Why is this behavior?
Because the context cannot create a scoped bean to inject if the target bean is not being constructed in that scope (e.g. trying to inject a request-scoped bean into a bean that's being created outside the context of a request).
To solve this you need to use scoped-proxies, by setting proxyMode.
In your specific case, however, the solution is that you don't actually need non-default scope.
#Scope- Isn't Compulsory to use with #Controller, unless and until u need one based on your requirements. #Scope defines the scope of the bean, by default its singleton.
And also, Property Class should be managed by Spring, otherwise it will give you an exception.

Custom annotation like #Value

I need to create a means to add a custom annotation like
#Value("${my.property}")
However, in my case I need to get the value from a database rather then a properties file.
Basically I would like to create a bean on container startup that reads in property name value pairs from a database and can then inject these into fields belonging to other beans.
Approach #1:
One way is to create an Aspect, with a point-cut expression that matches any method having this annotation.
Your aspect will then:
Read the property value in the annotation
Look up the required value an inject it into the class.
AOP Kickstart
Here's a guide to getting started with AOP in Spring
http://www.tutorialspoint.com/spring/aop_with_spring.htm
Joinpoint matching
Here's a reference that describes how to create a join-point that matches on annotations: http://eclipse.org/aspectj/doc/next/adk15notebook/annotations-pointcuts-and-advice.html
Approach #2:
Another way is to use a BeanFactoryPostProcessor - this is essentially how a PropertyPlaceholderConfigurer works.
It will look at your bean definitions, and fetch the underlying class.
It will then check for the annotation in the class, using reflection.
It will update the bean definition to include injecting the property as per the value in the annotation.
. . actually I think approach #2 sounds more like what you want - all of the processing happens on "start-up". . . (In actual fact your modifying the bean recipes even before startup). . whereas if you used AOP, you'd be intercepting method invocations, which might be too late for you?
Namespace Handler
If you wanted you could even create your own Spring namespace handler to turn on your post processor in a terse way. Eg:
<myApp:injectFromDb />
as an alternative to:
<bean class="MyDatabaseLookupProcessorImpl etc, etc. />
Update: Approach #3
As of Spring 3.1 there's also the PropertySourcesPlaceholderConfigurer, that will provide most of the plumbing for you, so you can achieve this with less code.
Alternatively you should be able to configure kind of properties repository bean and then use it in SpEL directly in #Value annotation.
Let's say you'd have bean called propertiesRepository in your context that implements following interface:
interface PropertiesRepository {
String getProperty(String propertyName);
}
then on bean where you want to inject values you can use following expression
#Value("#{propertiesRepository.getProperty('my.property')}")
String myProperty;
You can use #Value annotation by injecting database configuration in application environment itself.
I know this is an old question but I didn't find an exact solution. So documenting it here.
I have already answered the same on different forum.
Please refer to this answer for exact solution to your problem.

object creation in spring

If I am using spring frame work in my application does creating an object like this Test test = new Test() a bad way for creating an instance? Should I always use the bean config to get the objects/bean that I need? If yes, does that means I should have all the object/bean definition in spring applicationContext xml file?
If you want your object to be managed by Spring (this means that dependencies are injected, among other things) you have to use the ApplicationContext.
Calling Test test = new Test() isn't illegal, or even bad practice. It just means that Spring will have no awareness of this object, and it won't bother autowiring it's dependencies, or doing anything else that you'd expect Spring to do.
You don't necessarily need to use the applicationContext.xml file for ALL of your bean declarations. Many people favor annotations, which allow you to declare beans outside of the applicationContext.xml file.
It's worth nothing that Spring-managed beans are by default singletons (think of Servlets). If you want stateful beans that are Spring aware, you could use an ObjectFactoryCreatingFactoryBean to do something like this:
#Autowired
private ObjectFactory myWidgetFactory;
public void doStuff() {
Widget w = myWidgetFactory.getObject();
}
You can read more about this behaviour here:
http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/beans/factory/config/ObjectFactoryCreatingFactoryBean.html
For me there's a big difference between objects that represent components of my application -- services, controllers, DAOs, utilities, etc. -- and objects that represent entities within my application -- Person, Order, Invoice, Account, etc. The former type of objects should absolutely be managed by Spring and injected. The latter type are typically created on the fly by the application, and that frequently will involve calling new. This is not a problem.
Test test = new Test() a bad way for
creating an instance?
Yes it is bad practice.
Should I always use the bean config
to get the objects/bean that I need?
Yes, if you are using Spring for dependency injection.
If yes, does that means I should have
all the object/bean definition in
spring applicationContext xml file?
Always! You could use Annotations too.

Resources