Skip to the content.

What is dependency injection and what are the advantages of using it?

Dependency injection is a design pattern that promotes loose coupling between the Spring components – that is, between the different collaborating POJOs. So by applying DI to your complex programming, your code will become simpler, easier to understand, and easier to test. According to the DI pattern, dependent objects are given their dependencies at the time of creation of the objects by some factory or third party. This means that we have to focus on defining the dependencies instead of resolving the dependencies of collaborating objects in the enterprise application. Advantages:

What is an interface and what are the advantages of making use of them in Java?

A Java (Java 8 and later) interface is a reference that can contain the following:

What is an ApplicationContext?

In the Spring Framework, the org.springframework.beans.factory.BeanFactory interface provides the bean factory, which is a Spring IoC container. The bean factory is merely an object pool where objects are created and managed by configuration. The interface org.springframework.context.ApplicationContext is simply a wrapper of the bean factory, providing some extra application context services, such as support for AOP and, hence, declarative transaction, security, and instrumentation support such as support for message resources required for internationalization, and the ability to publish application events to interested event listeners. There can be more than one application context in a single Spring application. Multiple application contexts can be arranged in a parent-child hierarchy where the relation is directional from child context to parent context. Many child contexts can have one and the same parent context.

How are you going to create a new instance of an ApplicationContext?

Spring provides several flavours of application context as a bean container. There are multiple core implementations of the ApplicationContext interface:

Spring provides you with a web-aware implementation of the ApplicationContext interface, as shown here:

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

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

Pointcut

  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 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 tag, the destroyMethod attribute of the `@Bean` annotation, and JSR 250's `@PreDestroy` annotation.

How are you going to create an ApplicationContext in an integration test?

Depending on whether JUnit 4 or JUnit 5 is used, the annotation @RunWith (JUnit 4) or @ExtendWith (JUnit 5) is used to annotate the test-class. In addition, the annotation @ContextConfiguration in both cases to specify either the XML configuration file(s) or the Java class(es) containing the Spring configuration to be loaded into the application context for the test. JUnit 4

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

JUnit 5

@SpringJUnitConfig(classes=MyConfiguration.class)
public class JUnit5SpringTest {

SpringJUnitConfig combines these 2 annotations: @ExtendWith(SpringExtension.class) from JUnit 5 to run the test with the SpringExtension Class and `@ContextConfiguration from Spring Testing to load the Spring context.

Web Application Context

JUnit 4 @RunWith(SpringRunner.class) + @ContextConfiguration + @WebAppConfiguration JUnit 5 @SpringJUnitWebConfig combines the same annotations of @SpringJUnitConfig plus the @WebAppConfiguration

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

In a standalone non-web Spring application, there are two ways by which the Spring application context can be closed:

Web Application

In a web application, closing of the Spring application context is taken care of by the ContextLoaderListener, which implements the ServletContextListener interface. The ContextLoaderListener will receive a ServletContextEvent when the web container stops the web application.

Spring Boot Closing Application Context

Spring Boot will register a shutdown-hook as described above when a Spring application that uses Spring Boot is started. The mechanism described above with the ContextLoaderListener also applies to Spring Boot web applications.

Are beans lazily or eagerly instantiated by default? How do you alter this behavior?

Singleton Spring beans in an application context are eagerly initialized by default, as the application context is created. An instance of a prototype scoped bean is typically created lazily when requested. To explicitly set whether beans are to be lazily or eagerly initialized, the @Lazy annotation can be applied either to:

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

What is a property source? A property source in Spring’s environment abstraction represents a source of key-value pairs. Examples of property sources are:

How would you use @PropertySource? The simplest way to resolve external values in Spring is to declare a property source and retrieve the properties via the Spring Environment. NOTE! The annotation is applied to classes annotated with @Configuration.

@Configuration
@PropertySource("classpath:/com/soundsystem/app.properties") //<==Declare a property source
public class ExpressiveConfig {
    
    @Autowired
    Environment env;
    
    public BlankDisk disk() {
        return new BlankDisc (env.getProperty("disc.title"), env.getProperty("disc.artist")); //<== Retrieve property values
    }
}

Spring also offers the option of wiring properties with placeholder values that are resolved from a property source.

public BlankDisc(@Value("${disc.title}") String title, @Value("${disc.artist}") String artist) {
    this.title = title;
    this.artist = artist;
}

In order to use placeholder values, you must configure either a PropertyPlaceholderConfigurer bean (deprecated, use PropertySourcesPlaceholderConfigurer instead ) or a PropertySourcesPlaceholderConfigurer bean. The following @Bean method configures PropertySourcesPlaceholderConfigurer in Java configuration:

@Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
    return new PropertySourcesPlaceholderConfigurer();    
}

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

Create and Initialize Beans

As you can see in the preceding diagram, the initialization phase is divided into these two steps:

Load bean definitions In this step, all the configuration files – @Configuration classes or XML files – are processed. For Annotation-based configuration, all the classes annotated with @Components are scanned to load the bean definitions. Spring provides multiple BeanFactoryPostProcessor beans, so, it is invoked to resolve runtime dependencies such as reading values from external property files. In a Spring application, BeanFactoryPostProcessor can modify the definition of any bean. To influence the order in which bean factory post processors are invoked, their bean definition methods may be annotated with the @Order annotation. If you are implementing your own bean factory post processor, the implementation class can also implement the Ordered interface.

Bean Factory Post Processor

BeanFactory object is passed as an argument to the postProcess() method of BeanFactoryPostProcessor. Let’s see how BeanFactoryPostProcessor works, and how to override it in our application:

Example: Here, we’ll use the DataSource bean to be configured with the database values such as username, password, db url, and driver. So, in the preceding code, how do we resolve the @Value and ${..} variables? We need a PropertySourcesPlaceholderConfigurer to evaluate them. This is a BeanFactoryPostProcessor.

jdbc.driver=org.hsqldb.jdbcDriver
jdbc.url=jdbc:hsqldb:hsql://production:9002
jdbc.username=doj
jdbc.password=doj@123
@Configuration
@PropertySource("classpathL/config/database.properties")
public class InfraConfig {
    @Bean
    public DataSource dataSource(
            @Value("${jdbc.driver}") String driver,
            @Value("${jdbc.url") String url,
            @Value("${jdbc.user") String user,
            @Value("${jdbc.password") String pwd) {
        DataSource ds = new BasicDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUser(user);
        ds.setPassword(pwd);
        return ds;
    }
}

What is a BeanPostProcessor and how is it different to a BeanFactoryPostProcessor? What do they do? When are they called?

@Bean(initMethod = "populateCache")
public AccountRepository accountRepository() {
    return new JdbcAccountRepository();
}

@PostConstruct
void populateCache() {
    System.out.println("Called populateCache() method");    
}

Causes init (@PostConstruct) methods to be called. Internally, Spring uses several BeanPostProcessors (BPPs). For example CommonAnnotationBeanPostProcessor to enable initialization.

BeanPostProcessors operate on bean (or object) instances; that is to say, the Spring IoC container instantiates a bean instance and then BeanPostProcessors do their work. BeanPostProcessors are scoped per-container.

Configuration Lifecycle

BeanPostProcessor vs BeanFactoryPostProcessor

  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).

Examples of BeanPostProcessor are:

What does component-scanning do?

To do dependency injection, Spring creates a so-called application context. During startup, Spring instantiates objects and adds them to the application context. Objects in the application context are called “Spring beans” or “components”. Spring resolves dependencies between Spring beans and injects Spring beans into other Spring beans’ fields or constructors. The process of searching the classpath for classes that should contribute to the application context is called component scanning. Scan objects are: component, service, repository, controller

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

The following are the types of dependency injections that could be injected into your application:

Advantages of setter injection:

Disadvantage of the setter injection:

What is the behaviour of the annotation @Autowired? Autowiring is a mechanism which enables more or less automatic dependency resolution primarily based on types. The basic procedure of dependency injection with the @Autowired is:

The following are common for all the different use-cases of the @Autowired annotation:

@Autowired
public void setMovieCatalogs(Map<String, MovieCatalog> movieCatalogs) {
    this.movieCatalogs = movieCatalogs;    
}

@Autowired(required = Declares whether the annotated dependency is required)

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

Spring provides one more annotation, @Qualifier, to overcome the problem of disambiguation in autowiring DI. @Qualifier at Bean Definitions Qualifiers can also be applied on bean definitions by annotating a method annotated with @Bean in a configuration class with @Qualifier and supplying a value in the @Qualifier annotation. This will assign a qualifier to the bean and the same qualifier can later be used at an injection point to inject the bean in question. If a bean has not been assigned a qualifier, the default qualifier, being the name of the bean, will be assigned the bean.

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

A proxy object is an object that have the same methods, at least the public methods, as the object it proxies. The purpose of this is to make the proxy indistinguishable from the object it proxies.

JDK and CGLib Proxy

What does the @Bean annotation do?

Indicates that a method produces a bean to be managed by the Spring container. Has properties:

Typically, @Bean methods are declared within @Configuration classes. In this case, bean methods may reference other @Bean methods in the same class by calling them directly. @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. 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.

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

Default bean’s id is method’s name. To override it, use @Bean(name=”name”) or @Bean(“name”).

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

Configuration classes are subclassed by the Spring container using CGLIB and final classes cannot be subclassed.

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

In Java configuration, you can use the @Profile annotation to specify which profile a bean belongs to. The @Profile annotation may be used in any of the following ways:

Spring honors two separate properties when determining which profiles are active: spring.profiles.active and spring.profiles.default:

Note! You can activate multiple profiles at the same time by listing the profile names, separated by commas. If you would like to define alternative beans with different profile conditions, use distinct Java method names pointing to the same bean name via the @Bean name attribute, as indicated in the example above.

@Bean("dataSource")
@Profile("development")
public DataSource standaloneDataSource(){
@Bean("dataSource")
@Profile("production")
public DataSource jndiDataSource() throws Exception {

Note! Profile names in the @Profile annotation can be prefixed with !, indicating that the beans are to be registered when the profile with specified name is not active. The beans in the above configuration class will be registered if any profile except the “prod” Testing with profiles

Spring offers the @ActiveProfiles annotation to let you specify which profile(s) should be active when a test is run.

Can you use @Bean together with @Profile?

Yes

Can you use @Component together with @Profile?

Yes

How many profiles can you have?

Integer.Max

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

Scalar/literal values can be injected into Spring beans using the @Value annotation. Such values can originate from environment variables, property files, Spring beans etc.

@Value("${some.key:my default value}")
private String stringWithDefaultValue;

Similarly, we can set a zero-length String as the default value:

@Value("${some.key:}")
private String stringWithBlankDefaultValue;

To set a default value for primitive types such as boolean and int, we use the literal value:

@Value("${some.key:true}")
private boolean booleanWithDefaultValue;

@Value("${some.key:42}")
private int intWithDefaultValue;

We can also inject a comma-separated list of values into an array:

@Value("${some.key:one,two,three}")
private String[] stringArrayWithDefaults;

@Value("${some.key:1,2,3}")
private int[] intArrayWithDefaults;

What is Spring Expression Language (SpEL for short)?

The Spring Expression Language is an expression language used in the different Spring products, not only in the Spring framework. SpEL expressions are framed with #{ … }. SpEL has support for: Literal expressions Boolean and relational operators Regular expressions Class expressions Accessing properties, arrays, lists, maps Method invocation Relational operators Assignment Calling constructors Bean references Array construction Inline lists Ternary operator Variables User defined functions Collection projection Collection selection Templated expressions

What is the Environment abstraction in Spring?

The Environment is an abstraction integrated in the container that models two key aspects of the application environment: profiles and properties. A profile is a named, logical group of bean definitions to be registered with the container only if the given profile is active. @PropertySource Annotation providing a convenient and declarative mechanism for adding a PropertySource to Spring’s Environment. To be used in conjunction with @Configuration classes. Given a file app.properties containing the key/value pair testbean.name=myTestBean, the following @Configuration class uses @PropertySource to contribute app.properties to the Environment’s set of PropertySources.

Where can properties in the environment come from – there are many sources for properties – check the documentation if not sure. Spring Boot adds even more.

Property Source Originating Environment
JVM system properties StandardEnvironment
System environment variable StandardEnvironment
Servlet configuration properties (ServletConfig) StandardServletEnvironment
Servlet context parameters (ServletContext) StandardServletEnvironment
JNDI properties StandardServletEnvironment
Command line properties n/a
Application configuration (properties file) n/a
Server ports n/a
Management server n/a

Spring Boot uses a very particular PropertySource order that is designed to allow sensible overriding of values. Properties are considered in the following order:

  1. Devtools global settings properties on your home directory (~/.spring-boot- devtools.properties when devtools is active).
  2. @TestPropertySource annotations on your tests.
  3. @SpringBootTest#properties annotation attribute on your tests.
  4. Command line arguments.
  5. Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property).
  6. ServletConfig init parameters.
  7. ServletContext init parameters.
  8. JNDI attributes from java:comp/env.
  9. Java System properties (System.getProperties()).
  10. OS environment variables.
  11. A RandomValuePropertySource that has properties only in random.*.
  12. Profile-specific application properties outside of your packaged jar (application- {profile}.properties andYAMLvariants).
  13. Profile-specific application properties packaged inside your jar (application- {profile}.properties andYAMLvariants).
  14. Application properties outside of your packaged jar (application.properties and YAML variants).
  15. Application properties packaged inside your jar (application.properties and YAML variants).
  16. @PropertySource annotations on your @Configuration classes.
  17. Default properties (specified by setting SpringApplication.setDefaultProperties).

What can you reference using SpEL?

Referencing beans, properties, and methods Reference bean by id: #{sgtPeppers} bean whose ID is sgtPeppers Reference bean property: #{sgtPeppers.artist} Bean’s method: #{artistSelector.selectArtist()},#{artistSelector.selectArtist().toUpperCase()} To guard against a NullPointerException, you can use the type-safe operator: #{artistSelector.selectArtist()?.toUpperCase()}

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

Expressions in @Value annotations are of two types:

References

  1. MrR0807 Spring certification notes
  2. Moss Green Spring certification notes
  3. Spring Documentation
  4. Spring Boot Documentation