-
Notifications
You must be signed in to change notification settings - Fork 0
Understanding Spring
In this project, diving right in and writing code with the flow is possible. However, it's important to acknowledge that Spring has a challenging learning curve, and not having a proper grasp of its core features might lead to some headaches. While the official documentation may be limited, the community has contributed numerous articles and tutorials, which can serve as valuable resources. This section aims to provide a concise overview of Spring and Spring Boot, their benefits, and pointers to further information.
Spring:
- Lightweight framework widely used to develop Java (or Kotlin) applications.
- Its most important feature is dependency injection, which promotes loose coupling and modularity.
- Offers a vast number of modules that you can use independently from each other (e.g. Spring JDBC, Spring Security, Spring MVC).
- Doesn't offer features for creating servers, databases, or dependency management.
- Still has considerable boilerplate, in exchange for more freedom and flexibility.
Spring Boot:
- Built on top of Spring, providing all its features while being easier to use.
- Widely used to develop REST APIs (as in our case).
- Its most important feature is autoconfiguration, which automates the setup process and minimizes manual configurations.
- Features embedded servers, in-memory database, and dependency management.
- Greatly reduces boilerplate and lines of code, although it offers less freedom compared to the base Spring framework.
In sum, Spring Boot's motto is taking an opinionated view of the Spring platform, which paves the way for faster and more efficient development.
Sources: Baeldung, GeeksForGeeks, and JavaTPoint.
As previously said, one of Spring's main features is dependency injection. To understand how this works, we need to learn about Spring Components and Beans.
Any class annotated with @Component
will be considered a Spring Component, which is managed by the Spring Container. This allows Spring to detect that class, instantiate them (which are now named beans) and provide them via dependency injection. There are more annotations to mark components, used to convey the roles of the classes, such as @Controller
, @Service
, and @Repository
.
@Component
class MyComponent {
// Class implementation
}
Additionally, you can use @Bean
to explicitly define beans configured in a function. They are commonly used in @Configuration
classes:
@Configuration
class MyConfig {
@Bean
fun myBean(): MyBean {
return new MyBean();
}
}
Read more about configuration on the Configuration page.
With your beans defined, you can use them in all your classes without the need to instantiate or configure dependencies ever again! There are 3 ways we use them in our project:
- Inject them directly into a component's constructor
@Service
class AccountService(
private val repository: AccountRepository,
private val encoder: PasswordEncoder,
private val fileUploader: FileUploader
) {
// Service implementation
}
- Use
@Autowired
in a non-component class
@ControllerTest
class AccountControllerTest @Autowired constructor(
val mockMvc: MockMvc,
val objectMapper: ObjectMapper,
val repository: AccountRepository
)
- Use the application's context
There are some rare cases where Spring won't be able to inject dependencies in the constructor (e.g. the abstract non-component EntityDto
class). In this case, we can request beans at runtime using our custom class ApplicationContextUtils
:
companion object {
private val objectMapper = ApplicationContextUtils.getBean(ObjectMapper::class.java)
private val validator = ApplicationContextUtils.getBean(Validator::class.java)
}
Getting Started
Architecture Details
Implementation Details
Testing
Documentation
Deployment