Spring — Dependecy Injection and IOC Q&A

1- What is dependency injection and what are the advantages?

  • Reduced coupling between the parts of an application.
  • Increased cohesion of the parts of an application.
  • Increased testability.
  • Better design of applications when using dependency injection.
  • Increased reusability.
  • Increased maintainability.
  • Standardizes parts of application development.
  • Reduces boilerplate code.

2- What is meant by “application-context”?

3- What is the concept of a “container” and what is its lifecycle?

  • Bean factory
  • Application contexts
  1. Spring container is created as the application is started.
    2. The container reads configuration data.
    3. Bean definitions are created from the configuration data.
    4. Bean factory post-processors processes the bean definitions (BeanFactoryPostProcessor interface)
    5. Spring beans are instantiated by the container using the bean definitions.
    6. Spring beans are configured and assembled. Property values and dependencies are injected into the beans by the container.
    7. Bean post-processors processes the beans in the container and any initialization callbacks are invoked on the beans. Bean post-processors are called both before and after any initialization callbacks are invoked on the bean. (BeanPostProcessor interface).
    8. The application runs.
    9. Application shut down is initialized.
    10. The Spring container is closed.
    11. Destruction callbacks are invoked on the singleton Spring beans in the container. In Spring, an object implementing the ApplicationContext interface is a container.

4- How can we create a new instance of an ApplicationContext?

  • FileSystemXmlApplicationContext
  • ClassPathXmlApplicationContext
  • AnnotationConfigApplicationContext
  • XmlWebApplicationContext
  • AnnotationConfigWebApplicationContext
ApplicationContext context = new FileSystemXmlApplicationContext(“c:/knight.xml”);ApplicationContext context = new ClassPathXmlApplicationContext(“knight.xml”); ApplicationContext context = new AnnotationConfigApplicationContext( com.springinaction.knights.config.KnightConfig.class);

5- Can you describe the lifecycle of a Spring Bean in an ApplicationContext?

  1. Load all bean definitions, creating an ordered graph.
  2. Instantiate and run BeanFactoryPostProcessors (you can update bean definitions here).
  3. Instantiate each bean.
  4. Spring injects the values and bean references into the beans’ properties.
  5. Spring passes the ID of the bean to the setBeanName() method of the BeanNameAware interface if any bean implements it.
  6. Spring passes the reference of the bean factory itself to the setBeanFactory() method of BeanFactoryAware if any bean implements it.
  7. Spring passes the reference of the application context itself to the setApplicationContext() method of ApplicationContextAware if any bean implements it.
  8. BeanPostProcessor is an interface, and Spring allows you to implement it with your bean, and modifies the instance of the bean before the initializer is invoked in the Spring bean container by calling its postProcessBeforeInitialization().
  9. If your bean implements the InitializingBean interface, Spring calls its afterPropertiesSet() method to initialize any process or loading resource for your application. There are other methods to achieve this step, for example, you can use the init-method of the <bean> tag, the initMethod attribute of the @Bean annotation, and JSR 250’s @PostConstruct annotation.
  10. BeanPostProcessor is an interface, and spring allows you to implement it with your bean. It modifies the instance of the bean after the initializer is invoked in the spring bean container by calling its postProcessAfterInitialization().
  11. Now your bean is ready to use in the step, and your application can access this bean by using the getBean() method of the application context. Your beans remain live in the application context until it is closed by calling the close() method of the application context.
  12. If your bean implements the DisposibleBean interface, Spring calls its destroy() method to destroy any process or clean up the resources of your application. There are other methods to achieve this step-for example, you can use the destroy-method of the <bean> tag, the destroyMethod attribute of the @Bean annotation, and JSR 250’s @PreDestroy annotation.

6- How can we create an ApplicationContext in an integration test ?

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = MyConfiguration.class)
public class JUnit4SpringTest {
@Autowired
protected MyBean myBean;

@Autowired
protected ApplicationContext applicationContext;
}
@SpringJUnitConfig(classes = MyConfiguration.class)
public class JUnit5Springtest {
// JUnit 4
@RunWith(SpringRunner.class) + @ContextConfiguration + @WebAppConfiguration
// JUnit 5
@SpringJUnitWebConfig combines the same annotations of @SpringJUnitConfig plus the @WebAppConfiguration

7- What is the preferred way to close an application context? Does Spring Boot do this for you?

  • Registering a shutdown-hook by calling the method registerShutdownHook, also implemented in the AbstractApplicationContext class. This is recommended way
  • Calling the close method from the AbstractApplicationContext class.

8- Dependency injection using Java configuration?

@Bean
public CompactDisc sgtPeppers() {
return new SgtPeppers();
}
@Bean
public CDPlayer cdPlayer() {
return new CDPlayer(sgtPeppers());
}
@Bean
public CDPlayer cdPlayer(CompactDisc compactDisc) {
return new CDPlayer(compactDisc);
}

9- Dependency injection using annotations (@Component, @Autowired)?

@Configuration
@ComponentScan
public class CdPlayerConfig {
}
@Configuration
@ComponentScan(basePackages = "soundsystem")
public class CDPlayerConfig {}
@Configuration
@ComponentScan(basePackages = {"soundsystem", "video"})
public class CDPlayerConfig {}
@Configuration
@ComponentScan(basePackageClasses = {CDplayer.class, DVDPlayer.class})
public class CDPlayerConfig {}

10- Component scanning, Stereotypes and Meta-Annotations?

11- Scopes for Spring beans? What is the default scope?

12- Are beans lazily or eagerly instantiated by default? How do you alter this behaviour?

  • Methods annotated with the @Bean annotation. Bean will be lazy or not as specified by the boolean parameter to the @Lazy annotation (default value is true).
  • Classes annotated with the @Configuration annotation. All beans declared in the configuration class will be lazy or not as specified by the boolean parameter to the @Lazy annotation (default value is true).
  • Classes annotated with @Component or any related stereotype annotation. The bean created from the component class will be lazy or not as specified by the boolean parameter to the @Lazy annotation (default value is true).

13- What is a property source? How would you use @PropertySource?

  • The system properties. System.getProperties()
  • Properties in a JNDI environment
  • Properties files.
@Configuration
@PropertySource("classpath:/com/soundsystem/app.properties")
public class ExpressiveConfig {
@Autowired
Environment env;
public BlankDisc disc() {
return new BlankDisc(env.getProperty("disc.title"), env.getProperty("disc.artist"));
}
}
public BlankDisc(@Value("${disc.title}") String title, ...){
this.title = title;
}
@Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer(){
return new PropertySourcesPlaceholderConfigurer();
}

14- What is a BeanFactoryPostProcessor and what is it used for? When is it invoked?

  • Load bean definitions. Create an ordered graph
  • Instantiate and run BeanFactoryPostProcessors (you can update bean definitions here).
  • Initialize bean instances
  • BeanFactoryPostProcessor works on the bean definitions or the configuration metadata of the bean before the beans are actually created.
  • Spring provides several useful implementations of BeanFactoryPostProcessor, such as reading properties and registering a custom scope.
  • You can write your own implementation of the BeanFactoryPostProcessor interface.
  • If you define a BeanFactoryPostProcessor in one container, it will only be applied to the bean definitions in that container.

15- Why would you define a static @Bean method?

@Bean
public static PropertySourcesPlaceholderConfigurer pspc(){
// instantiate, configure and return pspc ...
}

16- What is a ProperySourcesPlaceholderConfigurer used for?

17- What is a BeanPostProcessor and how is it different to a BeanFactoryPostProcessor?

@Bean(initMethod = "populateCache")
public AccountRepository accountRepository(){
return new JdbcAccountRepository();
}
@PostConstruct
void populateCache(){
System.out.println("Called populateCache() method");
}
  1. A bean implementing BeanFactoryPostProcessor is called when all bean definitions will have been loaded, but no beans will have been instantiated yet. This allows for overriding or adding properties even to eager-initializing beans. This will let you have access to all the beans that you have defined in XML or that are annotated (scanned via component-scan).
  2. A bean implementing BeanPostProcessor operate on bean (or object) instances which means that when the Spring IoC container instantiates a bean instance then BeanPostProcessor interfaces do their work.
  3. BeanFactoryPostProcessor implementations are “called” during startup of the Spring context after all bean definitions will have been loaded while BeanPostProcessor are “called” when the Spring IoC container instantiates a bean (i.e. during the startup for all the singleton and on demand for the proptotypes one).

18- What is an initialization method and how is it declared on a Spring bean?

  • InitializingBean (afterPropertiesSet()) and DisposableBean (destroy()) callback interfaces
  • Custom @Bean init() and destroy() methods
  • @PostConstruct and @PreDestroy annotations

19- What is a destroy method, how is it declared and when is it called?

@Bean(destroyMethod = "")
public MyBeanClass myBean() {
final MyBeanClass theBean = new MyBeanClass();
return theBean;
}

20- Consider how you enable JSR-250 annotations like @PostConstruct and @PreDestroy? When/how will they get called?

21- What is the behavior of the annotation @Autowired with regards to field injection, constructor injection and method injection?

  • Constructor-based dependency injection
  • Setter-based dependency injection
  • Field-based dependency injection
  • It is more suitable for mandatory dependencies, and it makes a strong dependency contract
  • It provides a more compact code structure than others
  • It supports testing by using the dependencies passed as constructor arguments to the dependent class
  • It favours the use of immutable objects, and does not break the information hiding principle
  • It may cause circular dependency. (Circular dependency means that the dependent and the dependency class are also dependents on each other, for example, class A depends on Class B and Class B depends on Class A). Spring IoC container detects this circular reference at runtime, and throws a BeanCurrentlyInCreationException.
  • It is more readable than the constructor injection
  • It solves the circular dependency problem in the application
  • It allows costly resources or services to be created as late as possible, and only when required
  • It does not require the constructor to be changed, but dependencies are passed through public properties that are exposed
  • Security is lesser in the setter injection pattern, because it can be overridden
  • A setter-based dependency injection does not provide a code structure as compact as the constructor injection

22- What is the behaviour of the annotation @Autowired?

  • The Spring container examines the type of the field or parameter that is to be dependency injected.
  • The Spring container searches the application context for a bean which type matches the type of the field or parameter.
  • If there are multiple matching bean candidates and one of them is annotated with @Primary, then this bean is selected and injected into the field or parameter.
  • If there are multiple matching bean candidates and the field or parameter is annotated with the @Qualifier annotation, then the Spring container will attempt to use the information from the @Qualifier annotation to select a bean to inject.
  • If there is no other resolution mechanism, such as the @Primary or @Qualifier annotations, and there are multiple matching beans, the Spring container will try to resolve the appropriate bean by trying to match the bean name to the name of the field or parameter. This is the default bean resolution mechanism used when autowiring dependencies.
  • If still no unique match for the field or parameter can be determined, an exception will be thrown.
  • Dependency injection, regardless of whether on fields, constructors or methods, is performed by the AutowiredAnnotationBeanPostProcessor. Due to this, the @Autowired annotation cannot be used in neither BeanPostProcessor-s nor in BeanFactoryPostProcessor-s.
  • All dependencies annotated with @Autowired are required as default and an exception will be thrown if such a dependency cannot be resolved.
  • If the type that is autowired is an array-type, then the Spring container will collect all beans matching the value-type of the array in an array and inject the array.
  • If the type that is autowired is a collection type, then the Spring container will collect all beans matching the collection’s value-type in a collection of the specified type and inject the collection.
  • If the type that is autowired is a Map, then as long as the expected key type is String Map values will contain all beans of the expected type, and the keys will contain the corresponding bean names.
  • Alternatively, you may express the non-required nature of a particular dependency through Java 8’s java.util.Optional
  • Constructor, method and parameter can have any access modifier visibility

23- What do you have to do, if you would like to inject something into a private field?

  • Constructor
  • Setter
  • Mark @Autowired on field
  • Use @Value

24- How does the @Qualifier annotation complement the use of @Autowired?

25- What is a proxy object and what are the two different types of proxies Spring can create?

  • JDK Proxy: This is also known as a dynamic proxy. Its API is built into the JDK. For this proxy, the Java interface is required
  • CGLib Proxy: This is NOT built into JDK. However, it is included in Spring JARS, and is used when the interface is not available. It cannot be applied to final classes or methods

26- What are the limitations of these proxies (per type)?

  • Requires the proxied object to implement at least one interface.
  • Only methods found in the implemented interface(s) will be available in the proxy object.
  • Proxy objects must be referenced using an interface type and cannot be referenced using a type of a superclass of the proxied object type. This unless of course the superclass implements interface(s) in question.
  • Does not support self-invocations. Self-invocation is where one method of the object invokes another method on the same object.
  • Requires the class of the proxied object to be non-final. Subclasses cannot be created from final classes.
  • Requires methods in the proxied object to be non-final. Final methods cannot be overridden.
  • Does not support self-invocations. Self-invocation is where one method of the object invokes another method on the same object.
  • Requires a third-party library. Not built into the Java language and thus require a library. The CGLIB library has been included into Spring, so when using the Spring framework, no additional library is required.

27- What is the power of a proxy object and where are the disadvantages?

  • Can add behaviour to existing beans. Examples of such behaviour: Transaction management, logging, security.
  • Makes it possible to separate concerns such as logging, security etc from business logic.
  • It may not be obvious where a method invocation is handled when proxy objects are used
  • A proxy object may chose not to invoke the proxied object
  • If multiple layers of proxy objects are used, developers may need to take into account the order in which the proxies are applied
  • Proxy object may incur overhead
  • Only methods with public visibility will be advised
  • Local or internal method calls within an advised class doesn’t get intercepted by proxy, so advise method of the aspect does not get fired/invoked

28- What are the advantages of Java Config? What are the limitations?

  • Regular Java refactoring tooling will work on Java configuration classes. Special tooling needed for Spring XML configuration files.
  • Type-checking performed by Java compiler and IDE.
  • Can be located in one or a few places, compared to annotation-based configuration that is more spread out.
  • Combining Spring Java configuration, JUnit and Mockito you can write flexible integration tests mocking only some Spring Beans.
  • Configuration classes cannot be final. Configuration classes are subclassed by the Spring container using CGLIB and final classes cannot be subclassed.

29- What does the @Bean annotation do?

  • destroyMethod
  • initMethod
  • name
  • value (alias for name())

30- What is the default bean id if you only use @Bean? How can you override this?

31- Why are you not allowed to annotate a final class with @Configuration?

32- How do @Configuration annotated classes support singleton beans?

33- Why can’t @Bean methods be final either?

34- How do you configure profiles? What are possible use cases where they might be useful?

  • At class level in @Configuration classes. Beans in the configuration class and beans in configuration(s) imported with @Import annotation(s).
  • At class level in classes annotated with @Component or annotated with any other annotation that in turn is annotated with @Component.
  • On methods annotated with the @Bean annotation. Applied to a single method annotated with the @Bean annotations.
  • Type level in custom annotations. Acts as a meta-annotation when creating custom annotations.
  • If spring.profiles.active is set, then its value determines which profiles are active.
  • If spring.profiles.active isn’t set, then Spring looks to spring.profiles.default.
  • If neither spring.profiles.active nor spring.profiles.default is set, then there are no active profiles, and only those beans that aren’t defined as being in a profile are created.
@Bean("dataSource")
@Profile("development")
public DataSource standaloneDataSource()
@Bean("dataSource")
@Profile("production")
public DataSource jndiDataSource() throws Exception {
@Bean("dataSource")
@Profile("!prod")
public DataSource standaloneDataSource()

35- Can you use @Bean together with @Profile?

36- Can you use @Component together with @Profile?

37- How many profiles can you have?

38- How do you inject scalar/literal values into Spring beans?

@Value("${personservice.retry-count}")
private int personServiceRetryCount;
@Value("${some.key:my default value}")
private String stringWithDefaultValue;
@Value("${some.key:}")
private String stringWithBlankValue;
@Value("${some.key:true}")
private boolean booleanWithDefaultValue;
@Value("${some.key:42}")
private int intWithDefaultValue;
@Value("${some.key:one, two, three}")
private String[] stringArrayWithDefaultValue;
@Value("${some.key:1, 2, 4}")
private int[] intArrayWithDefaultValue;

39- What is @Value used for?

  • Setting (default) values
  • Injecting property, environment values
  • Evaluate expressions and inject the result
  • Inject values from other Spring beans

40- What is the difference between $ and # in @Value expressions?

  • Expressions starting with $. Such expressions reference a property name in the application’s environment. These expressions are evaluated by the PropertySourcesPlaceholderConfigurer Spring bean prior to bean creation and can only be used in @Value annnotations.
  • Expressions starting with #. Spring Expression Language expressions parsed by a SpEL expression parser and evaluated by a SpEL expression instance.

--

--

linkedin.com/in/umut-altas

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store