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?
- 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.
}
}
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,
-
Using @ComponentScan as a Java annotation
- Enabling Component Scan
- Spring Boot default Package
- This is from the Spring boot documentation, but it mentions the dangers of component scanning without restrictions.
@Configuration @ComponentScan(basePackages="org.example") public class MyConfiguration{ ... }
-
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); } }
-
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>
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 {
...
}
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