What in the world are Spring beans?
I am yet to find a high-level definition of Spring beans that I can understand. I see them referenced often in Grails documentation and books, but I think that understanding what they are would be beneficial. So what are Spring beans? How can they be used? Do they have something to do with Dependency Injection?
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. These beans are created with the configuration metadata that you supply to the container, for example, in the form of XML
<bean/>
definitions.
More to learn about beans and scope from SpringSource:
When you create a bean definition what you are actually creating is a recipe for creating actual instances of the class defined by that bean definition. The idea that a bean definition is a recipe is important, because it means that, just like a class, you can potentially have many object instances created from a single recipe.
You can control not only the various dependencies and configuration values that are to be plugged into an object that is created from a particular bean definition, but also the scope of the objects created from a particular bean definition. This approach is very powerful and gives you the flexibility to choose the scope of the objects you create through configuration instead of having to 'bake in' the scope of an object at the Java class level. Beans can be defined to be deployed in one of a number of scopes
*IoC: Inversion of Control
Spring beans are just instance objects that are managed by the Spring container, namely, they are created and wired by the framework and put into a "bag of objects" (the container) from where you can get them later.
The "wiring" part there is what dependency injection is all about, what it means is that you can just say "I will need this thing" and the framework will follow some rules to get you the proper instance.
For someone who isn't used to Spring, I think Wikipedia Spring's article has a nice description:
Central to the Spring Framework is its inversion of control container, which provides a consistent means of configuring and managing Java objects using reflection. The container is responsible for managing object lifecycles of specific objects: creating these objects, calling their initialization methods, and configuring these objects by wiring them together.
Objects created by the container are also called managed objects or beans. The container can be configured by loading XML files or detecting specific Java annotations on configuration classes. These data sources contain the bean definitions which provide the information required to create the beans.
Objects can be obtained by means of either dependency lookup or dependency injection. Dependency lookup is a pattern where a caller asks the container object for an object with a specific name or of a specific type. Dependency injection is a pattern where the container passes objects by name to other objects, via either constructors, properties, or factory methods.
First let us understand Spring:
Spring is a lightweight and flexible framework.
Analogy:
Java Beans are classes that encapsulate many objects into a single object (the bean). The name "Bean" was given to encompass this standard, which aims to create reusable software components for Java.
Spring Bean: is an object, which is created, managed and destroyed in Spring Container. We can inject an object into the Spring Container through the metadata(either xml or annotation), which is called inversion of control.
Analogy: Let us assume farmer is having a farmland cultivating by seeds(or beans). Here, Farmer is Spring Framework, Farmland land is Spring Container, Beans are Spring Beans, Cultivating is Spring Processors.
Like bean life-cycle, spring beans too having it's own life-cycle.
img source
Following is sequence of a bean lifecycle in Spring:
-
Instantiate: First the spring container finds the bean’s definition from the XML file and instantiates the bean.
-
Populate properties: Using the dependency injection, spring populates all of the properties as specified in the bean definition.
-
Set Bean Name: If the bean implements
BeanNameAware
interface, spring passes the bean’s id tosetBeanName()
method. -
Set Bean factory: If Bean implements
BeanFactoryAware
interface, spring passes the beanfactory tosetBeanFactory()
method. -
Pre-Initialization: Also called post process of bean. If there are any bean BeanPostProcessors associated with the bean, Spring calls
postProcesserBeforeInitialization()
method. -
Initialize beans: If the bean implements
IntializingBean
,itsafterPropertySet()
method is called. If the bean has init method declaration, the specified initialization method is called. -
Post-Initialization: – If there are any
BeanPostProcessors
associated with the bean, theirpostProcessAfterInitialization()
methods will be called. -
Ready to use: Now the bean is ready to use by the application
-
Destroy: If the bean implements
DisposableBean
, it will call thedestroy()
method
Well you understood it partially. You have to tailor the beans according to your need and inform Spring container to manage it when required, by using a methodology populalrly known as IoC (Inversion of Control) coined by Martin Fowler, also known as Dependency Injection (DI).
You wire the beans in a way, so that you do not have to take care of the instantiating or evaluate any dependency on the bean. This is popularly known as Hollywood Principle.
Google is the best tool to explore more on this in addition to the links you would get flooded with here in this question. :)
A Bean is a POJO(Plain Old Java Object), which is managed by the spring container.
Spring containers create only one instance of the bean by default. This bean it is cached in memory so all requests for the bean will return a shared reference to the same bean.
The @Bean annotation returns an object that spring registers as a bean in application context. The logic inside the method is responsible for creating the instance.
When do we use @Bean annotation?
When automatic configuration is not an option. For example when we want to wire components from a third party library, because the source code is not available so we cannot annotate the classes with @Component.
A Real time scenario could be that someone wants to connect to Amazon S3 bucket. Because the source is not available he would have to create a @bean.
@Bean
public AmazonS3 awsS3Client() {
BasicAWSCredentials awsCreds = new BasicAWSCredentials(awsKeyId, accessKey);
return AmazonS3ClientBuilder.standard().withRegion(Regions.fromName(region))
.withCredentials(new AWSStaticCredentialsProvider(awsCreds)).build();
}
Source for the code above -> https://www.devglan.com/spring-mvc/aws-s3-java
Because I mentioned @Component Annotation above.
@Component Indicates that an annotated class is a "component". Such classes are considered as candidates for auto-detection when using annotation-based configuration and class path scanning.
Component annotation registers the class as a single bean.