How many Spring beans gets created in this case - java

I have a class called EmployeeService and which is annotated with #service annotation from spring framework
package com.sample.EmployeeService
#Service
public class EmployeeService {
}
and I also have entry in context.xml
<bean id="empSer" class ="com.sample.EmployeeService"
May I know how many bean has been created in psring container.

In here
Spring will scan all the classes with #Service annotation, register it as a bean, then it will inject the dependencies that have #Autowired annotation.
#Service
public class EmployeeService {
}
In here
The context.xml is Spring's advanced container. Similar to BeanFactory, it can load bean definitions, wire beans together
<bean id="empSer" class ="com.sample.EmployeeService"
Actually you get one single bean - whether context.xml it is loaded first or classes with #Service annotation
And
If first loaded context.xml and second loaded #Service annotation class, Spring Application overwrite by default as the beans are being loaded up into the factory

Related

Spring is not creating the bean for #service annotated class when one of its method is annotated with #transactional

The spring application is failing to start as it could not find a bean for a class annotated with a #Service to be autowired in a configuration class. But it is only occurring when I am annotating a method in the that particular service class with #Transactional. Why this is happening?
While you annotate your class by #Transactional spring use AOP and if your class is final and has no interfaces it cannot create a proxy on your class.

Why are #Configuration and #Service together? What extra are we getting?

Have seen below code. Why we need to use this Configuration and Service annotation together.
#Configuration
#Service
public class SomeClass{
#Bean
#Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
public MongoClient somemethod(#Value){
.....
return mongoClient;
}
Also #Bean default scope is singleton then why again mention
#Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
The #Service annotation makes SomeClass a bean, whereas the #Configuration and #Bean are intended to create bean definitions for classes that you did not write(i.e. library classes).
And indeed the default scope is a singleton so the annotation can be ommited.
#Configuraton and #Service annotations has different purposes.
#Configuration annotation indicates that a class declares one or more bean methods and may be processed by spring container to generate bean definitions and service requests for those beans at runtime.
#Service annotation indicates than an annotated class is a "Business Service Facade" or similar thing.
Singleton is the default scope for a Spring Bean. So it is not necessary to define its scope. However, for better clarity and understanding, you can highlight this fact by using the #Scope annotation.

SPRING BOOT annotation: are they required

Are #Component, #Service and #Repository optional in Spring Boot 2?
Example If have a controller class called FirstController annotated with #Controller, #RestController and #RequestMapping. I also have service classes called FirstService and SecondService and a repository called FirstRespository.
I didn't annotate any of the class except FirstController but still my application works.
Does this mean that those stereotype annotations are not required for your app to make it work? You just need it for convention and if you need to modify behaviour like scope etc.
Thanks for answering in advance.
They are not required in order for your application to work BUT they will not be picked up by Spring on your application launch nor you will have benefits of that annotation specification
#Component - generic stereotype for any Spring-managed component
#Repository - stereotype for the persistence layer
#Service - stereotype for service layer
Any code can pass when you write your Spring application, but annotation helps Spring to understand what should be created as a bean or a component and for which use.
Consider this:
#Service
public class MyService {
private IComponent component;
#Autowired
public MyService(IComponent component) {
this.preparingService = preparingService;
}
}
In order to autowire a class implementing IComponent, you need to have that class decorated with #Service or #Component in order for Spring to inject it into MyService when MyService is itself of course injected in your controller.

How are injected these classes into my Spring controller class?

I am pretty new in Spring and I have some doubts about how is injected some classes into a controller class.
Into my project I have this HomeController class:
#Controller
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
#Autowired
private MessageSource messageSource;
#Autowired
private Environment env;
.....................................................
.....................................................
.....................................................
}
My doubt is related to the 2 objects MessageSource messageSource and Environment env classes.
As you can see these classes are injected by the #Autowired annotation.
The problem is that I have not bean definition into my XML configuration for these classes. So why are correctly injected? Where are the definition of these bean?
Tnx
Automatic discovery of beans is based on the following rules:
1) Use context:annotation-config tag in spring-config.xml to let
Spring use Annotations
2) Use context:component-scan tag in
spring-config.xml and tell Spring the package in which to look for
auto-discovering beans
3) Use #Component annotation to mark a class
as a Spring auto-discoverable bean
If #Component annotation is used, then the bean declarations need not be declared in spring-config.xml
Spring mappings can be done with XML or with annotations.
In your case, if no XML defined, your MessageSource and Environment classes should be mapped by Spring annotations like #Component #Service or #Resource:
#Component
Indicates that an annotated class is a "component". Such classes are considered as candidates for auto-detection when using annotation-based configuration and classpath scanning.
#Autowired
#Autowired annotation will try to find a bean of type Foo in the spring context and will then inject the same.
#Resource
Similar to this is #Resource annotation that will try to find the bean with the name "foo". To summarize, #Autowired wires by type and #Resource wires by name.
Both the Environment and the MessageSource are closely tied to the inner workings of Spring Framework.
The environment is part of the application context and will be available for autowiring.
The ApplicationContext interface extends the MessageSource interface and will be available for autowiring as a message source, even if you have not defined your own message source bean. (If you define your own message source, the application context will delegate to that)

Java #Component class and #Configuration class with AnnotationConfigApplicationContext

I know springs AnnotationConfigApplicationContext is capable of accepting not only #Configuration classes as input but also plain #Component classes and classes annotated with JSR-330 metadata.
I have created AppConfig.java below without #Configuration annotation.
public class AppConfig {
#Bean(name="sampleService")
public SampleService getSampleService(){
return new SampleService();
}
}
Passed this class as my java config class to AnnotationConfigApplicationContext, it accepted and registered my service beans.
I did some modification on above same AppConfig like below.
#Component
public class AppConfig {
#Bean(name="sampleService")
public SampleService getSampleService(){
return new SampleService();
}
}
passed AppConfig to AnnotationConfigApplicationContext, it accepted and registered my service beans.
Question:
AnnotationConfigApplicationContext class is accepting the java config class with #Configuration, without #Configuration and with #Component annotations, what is the difference between #Component and #Configuration?
Why is it Accepting even without #Configuration annotation?
When to use #Configuration, and when to use #Component as java config class?
#Component
Indicates that an annotated class is a "component".
That is, in a context where component scanning is enabled, Spring generates bean definitions for #Component annotated types. These bean definitions end up being turned into beans.
#Configuration, which is itself annotated with
Indicates that a class declares one or more #Bean methods and may be
processed by the Spring container to generate bean definitions and
service requests for those beans at runtime, [...]
So any #Configuration type, for which Spring generates a bean, acts as a factory for beans.
The javadoc of #Bean states
#Bean methods may also be declared within classes that are not
annotated with #Configuration. For example, bean methods may be
declared in a #Component class or even in a plain old class. In such
cases, a #Bean method will get processed in a so-called 'lite' mode.
Bean methods in lite mode will be treated as plain factory methods by
the container (similar to factory-method declarations in XML), with
scoping and lifecycle callbacks properly applied. The containing class
remains unmodified in this case, and there are no unusual constraints
for the containing class or the factory methods.
In contrast to the semantics for bean methods in #Configuration
classes, 'inter-bean references' are not supported in lite mode.
Instead, when one #Bean-method invokes another #Bean-method in lite
mode, the invocation is a standard Java method invocation; Spring does
not intercept the invocation via a CGLIB proxy. This is analogous to
inter-#Transactional method calls where in proxy mode, Spring does not
intercept the invocation — Spring does so only in AspectJ mode.
So #Bean methods have full functionality in #Configuration annotated classes and limited functionality in #Component annotated classes.
why it is Accepting even without #Configuration annotation?
That's how the class is designed. An ApplicationContext is a BeanFactory. AnnotationConfigApplicationContext simply offers an extra way to register a bean definition.
When to use #Configuration, and when to use #Component as java config class?
These really completely separate goals. Follow the javadoc. When you need to setup an ApplicationContext, you can use an AnnotationConfigApplicationContext with a #Configuration annotated class. If you simply need a bean, annotate its type with #Component.
#Component annotation marks the Java class as a bean, but #Configuration annotation marks the Java class containing beans (methods that have #Bean annotation).
The #Bean annotation must use with #Configuration exactly to create Spring
beans.
In following class
#Component
public class AppConfig {
#Bean(name="sampleService")
public SampleService getSampleService(){
return new SampleService();
}
}
#Bean annotation is not any effect, and getSampleService() method will be plain old java method and will not be singleton, because as i mentioned, #Bean annotation must use with #Configuration, so it must be repaired as following:
#Configuration
public class AppConfig {
#Bean(name="sampleService")
public SampleService getSampleService(){
return new SampleService();
}
}
so replacing #Configuration annotation with any other annotation, or removing it, just make #Bean annotation ineffective and getSampleService() method will not be singleton anymore.

Categories