Dependency injection is a programming technique that makes a class independent of its dependencies. That enables you to replace dependencies without changing the class that uses them, and It reduces the risk that you have to change a class just because one of its dependencies changed. It also makes code easier to test What DI does is loosing coupling or decoupling.
Create beans
There are three ways to create beans: automatic configuration, JavaConfig, and XML.
Automatic Spring configuration
Component scanning is that Spring automatically discovers beans to be created in the application context. Autowiring is that Spring automatically satisfies bean dependencies.
@Component annotation identifies this class as a component class and serves as a clue to Spring that a bean should be created for the class.
1 | package soundsystem; |
Way 1 to enable component scanning
@ComponentScan enables component scanning in Spring.
@Configuration annotation identifies this as a configuration class
1 | package soundsystem; |
Way 2 to enable component scanning
1 | <?xml version="1.0" encoding="UTF-8"?> |
Wire beans with JavaConfig
The @Bean annotation tells Spring that this method will return an object that should be registered as a bean in the Spring application context.
This method annotated with @Bean should be in a configuration class annotated with @Configuration.
1 |
|
Wire beans with XML
When Spring encounters this
1 | <?xml version="1.0" encoding="UTF-8"?> |
Inject beans
CDPlayerTest takes advantage of Spring’s SpringJUnit4ClassRunner to have a Spring application context automatically created when the test starts. And the @ContextConfiguration annotation tells it to load its configuration from the CDPlayerConfig class. Because that configuration class includes @ComponentScan, the resulting application context should include the CompactDisc bean.
1 | package soundsystem; |
There are three ways to inject beans, please see another blog for more details.
Difference between @Component and @Bean
- @Component auto detects and configures the beans using classpath scanning whereas @Bean explicitly declares a single bean, rather than letting Spring do it automatically.
- @Component does not decouple the declaration of the bean from the class definition where as @Bean decouples the declaration of the bean from the class definition.
- @Component is a class level annotation whereas @Bean is a method level annotation and name of the method serves as the bean name.
- @Component need not to be used with the @Configuration annotation where as @Bean annotation has to be used within the class which is annotated with @Configuration.
- We cannot create a bean of a class using @Component, if the class is outside spring container whereas we can create a bean of a class using @Bean even if the class is present outside the spring container.
- @Component has different specializations like @Controller, @Repository and @Service whereas @Bean has no specializations.
Let’s say that you want to wire components from some third-party library into your application. Because you don’t have the source code for that library, there’s no opportunity to annotate its classes with @Component and @Autowired. Therefore, automatic configu- ration isn’t an option.
Especially when you import the client of another service.
1 |
|
Let’s consider I want specific implementation depending on some dynamic state. @Bean is perfect for that case.
1 |
|
Note
- By default, all beans in Spring are singletons
- Decoupling is essential for unit testing. DI is a great way to achieve decoupling
- @Inject and @Autowired are interchangeable in many cases except some subtle differences
Summary
the core of the Spring Framework is the Spring container. This container manages the lifecycle of the components of an application, creating those components and ensuring that their dependencies are met so that they can do their job.
Reference: Spring in Action
Thank you for reading!