Spring Core

AJAY NEGI
5 min readDec 14, 2020

--

Spring framework is used to remove dependencies from our programs and to reduce boilerplate code as much as possible. Before Spring framework EJB was in use but because of its complexity, programmers switched to Spring. Don’t worry, we will look at all the features of spring framework in this blog such as Dependency Injection, IOC etc.

Beans

If you want to learn spring framework, then you should know about beans. In spring, beans are nothing but the objects that you wanted in your application, the only difference is that these beans are not instantiated by yourself, they are instantiated and assembled by Spring IOC container. Cool right? 😃.

Bean contains the configuration metadata which help the container to know how to create a bean, its life cycle details and also about its dependencies.

Bean Scope

When you are defining a bean, you can also mention the scope for that bean. Like, if you want spring to create new instance of bean every time, then you should declare the scope as prototype but if you want spring to return the same instance every time then you should declare it as singleton and which also happens to be the default scope for defining bean. These are the two basic scopes which are given by the bean factory, but if you want additional scopes then you should make use of ApplicationContext. The scope which are given by ApplicationContext are request, session and global-session scope.

Inversion Of Control

Most when you write a program, you use library methods anywhere you want, however you want to make your program easy to code. But in the case of frameworks, a certain pattern is designed for you to write code, you cannot just simply insert framework anywhere you want in the program, you have to start with it. So basically when you are using framework you are not using framework inside your code rather you are writing your code inside framework. In other words, first you used to have control over your program but when you are using framework. it has control over your program hence inversion of control.

Dependency Injection

Many a times when we are writing a code we make objects which are dependent on other objects, in other words we are hard-coding them which is not a good coding practice beacuse what if you want to change the dependency in the future then you have to change it again and again. To avoid these kinds of situation spring has given us dependency injection in which you don’t have to give dependency yourself, spring will do that for you.

There are basically two ways through which dependencies are given which are:

  1. Constructor injection: The dependencies are injected when the object is created.
  2. Setter injection: The dependencies are injected when the setter method is called. If both the injection techniques are used at a same time, IOC container will give the preference to setter injection over constructor injection.

The main difference between setter injection and constructor injection is that if you want to inject partial dependencies, you can not make use of constructor injection. For example there are three properties in a class, having 3 argument constructor and 3 setter methods but you only want to pass the information for only one property then it is only possible by setter method.

IOC Container

IOC container is responsible for instantiating, configuring and assembling the spring beans. The container gets its instructions by reading the configuration metadata. Configuration metadata can be represented by using XML,annotations or Java code.

This image will let you understand how spring works, the application POJOs are combined with configuration metadata so that after the spring container is created and initialized, you will have fully configurable and executable system.

There are two types of spring IOC containers:

1. Bean Factory

2. AplicationContext

Bean Factory Container

This is the simplest container providing basic support for dependency Injection. It is an interface for advanced factory capable of maintaining a registry of different beans and their dependencies. The BeanFactory enables to read bean definitions and access them using the bean factory. XmlBeanFactory is one of the implementation of BeanFactory. In java code we write it as :

BeanFactory factory = new XmlBeanFactory(new FileInputStream("beans.xml");

Spring ApplicationContext

This is the sub-interface of BeanFactory

It includes all the functionalities of BeanFactory, on top of which it provides the following:

  1. Message Resource handling.
  2. Publish events to registered listeners using ApplicationListener interface.
  3. Loading of multiple(hierarchical) contexts, allowing each to be focused on a particular layer, for example the web layer of an application.
  4. Load resources such as file or URL.

This is how we use ApplicationContext in our java code:

ApplicationContext context = new ClassPathXmlApplicationContext("appplicationContext.xml");

@Bean Methods and inter-dependencies

Injecting by type

If there’s only one bean instance available to be injected to the injection target point then it will be injected successfully by type.

@Configuration
public class Config{
@Bean
public BeanA bean1(){
return new BeanA();
}
@Bean
public BeanB beanB(BeanA theBean){
return new BeanA(theBean);
}
}

Here I used Configuration annotation because Configuration annotation indicates that the class has @Bean definition methods. So Spring container can process the class and generate Spring Beans to be used in the application.

Injecting by name

If there are more than one instance of the same type available for a target injection point then there’s a conflict (ambiguity). Spring doesn’t know which particular instance to be injected in that case. If the name of parameter is same as bean’s definition method (the method annotated with @Bean) name then the dependency is resolved by name.

@Configuration
public class Config{
@Bean
public BeanA bean1(){
return new BeanA();
}
@Bean
public BeanA bean2(){
return new BeanA();
}
@Bean
public BeanB beanB(BeanA bean1){
return new BeanA(bean1);
}
}

Injecting by name to matching qualifier

If there’s an ambiguity then it can also be resolved if the injection point method parameter add a @Qualifier annotation with matching target bean’s name

@Configuration
public class Config{
@Bean
public BeanA bean1(){
return new BeanA();
}
@Bean
public BeanA bean2(){
return new BeanA();
}
@Bean
public BeanB beanB(@Qualifier("bean2") BeanA theBean){
return new BeanA(theBean);
}
}

Injecting by qualifiers

Ambiguity can also be resolve by using @Qualifier on the both sides. This is important when a bean provider method has already indented to be exposed as a @Qualifier per business logic sense, so that a particular bean’s implementation can be changed without updating all injection points.

@Configuration
public class Config{
@Qualifier("myBean")
@Bean
public BeanA bean1(){
return new BeanA();
}
@Bean
public BeanA bean2(){
return new BeanA();
}
@Bean
public BeanB beanB(@Qualifier("myBean") BeanA theBean){
return new BeanA(theBean);
}
}

Conclusion

Spring Core is really important to learn as it helps in avoiding boilerplate code and also helps in loose coupling of objects. I hope that now you would have much clearer understanding of spring core than you have before reading this blog. So see ya on the next blog. 😊

--

--

AJAY NEGI
AJAY NEGI

Written by AJAY NEGI

Software Engineer Trainee at Mount blue Technologies.

No responses yet