Table of Contents
Some background…
In this series of posts I will give the answers I found for each of the Core Spring 4.2 Study Guide questions (you can download the guide at http://vojtechruzicka.com/wp-content/uploads/2016/10/Core-Spring-4.2-Certification-Study-Guide.pdf)
Suppose you have 2 teams working on two different layers of the application: web and database. Well we use the Spring container for wiring these layers together.
1What is dependency injection and what are the advantages?
Inversion of Control in containers like Spring do something similar like:
If you were to join a meeting and want to ask a question you have the control if you ask it. But if the speaker is asked by the organizers to ask questions at the end of the presentation than from our (the listeners) point of view we are dealing with inversion of control. That is: the speakers fulfills the lack of answers and clarifications on its own by asking us if we have any questions.
The bean that will have its dependencies added by the container is not allowed to call the injector service, so as Cosmina Iuliana said in her certification preparation book (this is called “Hollywood principle”):
Don’t call us, we’ll call you!
That’s the main principle of Inversion of Control.
Dependency Injection is a form of Inversion of Control used by containers like Spring to customize beans (the bean – as objects managed by Spring IoC container are called beans) or apply some given implementations on objects whose customizations are defined using interfaces. Techniques used for customizing the beans are constructor and setter injection – in that case you have to define a constructor that will accept certain implementation for the object field as a parameter. DI may be used by passing parameters to a factory method that is to create the “customized” object. So upon object creation DI ensures for “right” (in that very context) customization of the object.
From the advantages of dependency injection I want to mention:
- Code is cleaner
- Code is more reusable – DI code becomes more generic and suitable for more implementations
- Decoupling is more effective – less/or no direct dependencies are used the bean is less prone to be affected by changes in its dependencies
- Classes become easier to test – interfaces or abstract classes are used for fields, one can use stubs or mocks implementations to be used while unit testing
2What is an interface and what are the advantages of making use of them in Java?
Interface is an abstract representation of a class. In Spring using an interface for some field in a class allows for automatic substituting with required specific implementation – this will be done by DI.
3What is meant by “application-context” and how do you create one?
Spring uses following types of containers for IoC over beans:
- BeansFactory – interface, a basic functionality container
- ApplicationContext – interface, a more advanced container that is a sub-interface of BeansFactory and adds enterprise-specific functionality to it.
There are numerous implementations of ApplicationContext interface and they differ in the way you supply the configuration metadata (info about how beans are to be made and configured/wired together).
For example we can initialize some ApplicationContext that uses XML as source for configuration metadata:
ApplicationContext context = new ClassPathXmlApplicationContext("somename.xml");
4What is the concept of a “container” and what is its lifecycle?
Spring container is an “environment” for the beans to live. The container creates, configures and wires beans together. Spring has many container implementations but actually you can divide them in 2 types:
- BeanFactory – a simple container with basic support for DI
- ApplicationContext – a more advanced container that has support for getting values from property files or sending events to different listeners.
Usually for developing ApplicationContext is used.
When an ApplicationContext is created several things happen:
- BeanDefinition creation
- Customizing BeanDefinitions by BeanFactoryPostProcessor
- Custom FactoryBeans creation
- BeanFactory instantiates beans instances
- Beans customization by BeanPostProcessor
Source: https://habrahabr.ru/post/222579/ (in russian)
5Dependency injection using Java configuration
In Spring as of version 4 the way beans (Spring IoC container managed objects) are to be configured is defined in configuration metadata. Configuration metadata can be represented in 4 ways:
- XML
- Java annotations
- Java code
- Groovy configuration
For DI using Java configuration you have to use a JavaConfig class. It is annotated with @Configuration. Inside that class you declare some methods that return beans (configured instances of certain POJO classes that will be available in Spring context) and these methods should be annotated with @Bean.
Here is an example:
package blog.codingideas
@Configuration
public class CustomConfig {
@Bean
public OurBeanClass ourBeanClass {
return new OurBeanClass();
}
}
Important to mention is the fact that the bean’s name in the context will be the same as method’s name and if you want a different name you will have to use the name attribute for the @Bean annotation.
@Bean(name="someCustomName")
For injecting one bean into another you just call the method that creates the bean and Spring intercepts the call so that the method returns the existing bean rather than running again:
package blog.codingideas
@Configuration
public class CustomConfig{
@Bean
public OurBeanClass ourBeanClass{
return new OurBeanClass();
}
@Bean
public BeanWithInjection beanWithInjection(){
return new BeanWithInjection(ourBeanClass());
}
}
Or alternatively set a parameter of some type that is already a bean to the method and everything will be autowired automatically:
package blog.codingideas
@Configuration
public class CustomConfig{
@Bean
public OurBeanClass ourBeanClass{
return new OurBeanClass();
}
@Bean
public BeanWithInjection beanWithInjection(OurBeanClass ourBeanClassObject){
return new BeanWithInjection(ourBeanClassObject);
}
}
For using this configuration class you have to use a suitable application context implementation. Usually you will use AnnotationConfigApplicationContext.
public static void main(String[] args){
ApplicationContext context = new AnnotationConfigApplicationContext(CustomConfig.class);
OurBeanClass bean = context.getBean(OurBeanClass.class);
/*
here you do something with the bean
*/
}
Application context may be instantiated without some specified configuration class and in that case you can supply it using .register() method.
public static void main(String[] args){
ApplicationContext context = new AnnotationConfigApplicationContext();
context.register(CustomConfig.class);
context.register(Config2.class);
context.refresh();
OurBeanClass bean = context.getBean(OurBeanClass.class);
/*
here you do something with the bean
*/
}
Pay attention to the .refresh() method.
There are also some more things to mention about @Configuration classes. You can:
- Use @Import for merging several @Configuration classes
- Use @Autowire and @Value inside @Configuration classes as these classes are beans themselves
Combining of XML and JavaConfig styles is possible in the following ways:
- XML-centric way
- JavaConfig centric way
The XML-centric way is done when you use mainly XML metadata and an XML-based application-config. For example you use ClassPathXmlApplicationContext. In this case you have to configure the XML metadata file so that it allows for using the @Configuration and @Autowired annotations in the JavaConfig classes that will be declared as beans. This is achieved by:
Hello Man,
I’m preparing the Spring 4.2 Certification Exam and I found your blog.
I want to say that it’s just wonderfull ! Really Many Thanks Man !
Sabri
Thanks. I’m glad it’s helpful.
Where do I find the answers marked as “(this is a question from Core Spring 4.2-4.3 Certification Study Guide)” ?
Sorry had no time to work on those.
Very shortly this site will be famous among all blog
users, due to it’s pleasant articles
Thanks 🙂