Mike's Blog

Getting Spring Certified | Continuing with annotation based dependency injection

By: Micheal Arsenault

Posted: January 5, 2021

Reading Time: 6 minutes

Tags: certification Java Spring

resources:

      While in Java based configuration you would still retain a distinct area for bean creation, or at least a distinct area where to define where beans are created, annotation based configuration uses metadata placed on the classes themselves to tell Spring the dependencies as well as specialized configuration metadata to tell Spring where the classes are.

      How does Spring know what class we want to have available for autowiring and what class should be ignored? After all, there will be some data classes that we wouldn’t just want injected into properties. Also, what happens if we have multiple objects that could satisfy an interface where the usage needs to be determined based on the deployment area?

  1. Spring makes use of @Component and it’s specializations in order to determine what should be handled by Spring.

@Component  // Tells Spring to pick up this class as a bean candidate
public class MyClass{
    // Just a POJO
    public MyClass(Dependency dependency){
        ...
        // Spring will auto use the constructor if there's only 1
        // otherwise, Spring will look for a default constructor
        // specified with @Autowired or JSR330 equivalent.
    } 
}

As of Spring Framework 4.3, an @Autowired annotation on such a constructor is no longer necessary if the target bean defines only one constructor to begin with. However, if several constructors are available and there is no primary/default constructor, at least one of the constructors must be annotated with @Autowired in order to instruct the container which one to use. See the discussion on [constructor resolution](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-autowired-annotation-constructor-resolution) for details.

1.9.2. Using @Autowired link icon

While this class has the @Component, Spring offers several meta-annotations from the @Component annotation. So you can use them in the places where @Component would be used, but they offer a sort of self documenting annotation to help you understand the use of a class’s usage


Great! Spring can now understand we have a class that needs to be used as a bean candidate, how does Spring find it?

You just need to tell Spring to look for them,

  1. Using @ComponentScan as a Java annotation

    @Configuration
    @ComponentScan(basePackages="org.example")
    public class MyConfiguration{
        ... 
    }
    
  2. Spring Boot performs this by default with its @SpringBootApplication

    package com.example.myapplication;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication // same as @Configuration @EnableAutoConfiguration @ComponentScan
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    }
    
  3. Using XML configuration with context:component-scan

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            https://www.springframework.org/schema/context/spring-context.xsd">
    
        <context:component-scan base-package="org.example"/>
    
    </beans>
    


The use of <context:component-scan> implicitly enables the functionality of <context:annotation-config>. There is usually no need to include the <context:annotation-config> element when using <context:component-scan>.

beans-scanning-autodetection link icon


It is important to understand that even with component scanning, there is still functionality to ensure only select elements are discovered and Spring provides the ability to customize how your class finds configuration metadata via component scanning:

@Configuration
@ComponentScan(basePackages = "org.example",
        includeFilters = @Filter(type = FilterType.REGEX, pattern = ".*Stub.*Repository"),
        excludeFilters = @Filter(Repository.class))
public class AppConfig {
    ...
}

Table 5. Filter Types
Filter Type Example Expression Description

annotation (default)

org.example.SomeAnnotation

An annotation to be present or meta-present at the type level in target components.

assignable

org.example.SomeClass

A class (or interface) that the target components are assignable to (extend or implement).

aspectj

org.example..*Service+

An AspectJ type expression to be matched by the target components.

regex

org\.example\.Default.*

A regex expression to be matched by the target components' class names.

custom

org.example.MyTypeFilter

A custom implementation of the org.springframework.core.type.TypeFilter interface.

1.10.4. Using Filters to Customize Scanninglink icon


A Spring application is not limited to a single type of configuration and you can mix and match them, the configuration can be a collection of elements that best suite the situation. So feel free to use the best tools for the job.

Now that we’ve gone though letting Spring know where to find the beans, let’s continue with the next question:


Scopes for Spring beans? What is the default scope?

      So what is a ‘scope’? In this context, a scope is the lifetime of the bean object that is provided. The default bean scope is a singleton and this means there will only be at most one object created by Spring in the ApplicationContext. Spring reads the configuration metadata and creates the appropriate scoped bean; these scoped beans allow for additional functionality because they’re proxied objects under the container’s control except for the Prototype scope, these are just created every time they’re requested and not managed by Spring’s container.

When beans are under Spring’s control there is the ability for different scopes to be combined when necessary see 1.5.3. Singleton Beans with Prototype-bean Dependencies


Table 3. Bean scopes
Scope Description

singleton

(Default) Scopes a single bean definition to a single object instance for each Spring IoC container.

prototype

Scopes a single bean definition to any number of object instances.

request

Scopes a single bean definition to the lifecycle of a single HTTP request. That is, each HTTP request has its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext.

session

Scopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.

application

Scopes a single bean definition to the lifecycle of a ServletContext. Only valid in the context of a web-aware Spring ApplicationContext.

websocket

Scopes a single bean definition to the lifecycle of a WebSocket. Only valid in the context of a web-aware Spring ApplicationContext.

1.5. Bean Scopeslink icon