JPA vs. JDBC Starter Dependency Hierarchy
The spring-boot-starter-data-jpa artifact inherently depends on spring-boot-starter-jdbc. This establishes the JDBC starter as the foundational data access layer, while JPA operates as a higher-level abstraction built on top of it.
Spring Data JPA Overview
Spring Data JPA serves as a powerful abstraction that drastically reduces boilerplate code in the data access layer. By simply defining repository interfaces, developers gain fully implemented CRUD operations and query derivation without writing explicit SQL or interacting directly with the EntityManager.
Transition from spring.factories to imports Files
Historically, Spring Boot leveraged the META-INF/spring.factories file to register auto-configuration classes. This mechanism is currently being deprecated in favor of the imports file located under META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports, which provides a cleaner and more structured approach for declaring third-party auto-configurations.
Discouraging Field Injection
Using @Autowired directly on class fields is highly discouraged. Field injection hides class dependencies, makes components harder to unit test, and can lead to NullPointerExceptions. Constructor injection is the preferred alternative as it enforces immutability and explicitly declares required dependencies.
Distinction Between @Configuration and @Component
While both annotations register beans within the Spring context, @Configuration is backed by CGLIB proxying. This ensures that invoking a @Bean method within the same class returns the singleton managed by the container. Conversely, @Component lacks this proxying mechanism, meaning local method calls to @Bean methods will instantiate new, unmanaged objects.
Spring Security Exception Handling
When authentication fails, custom entry points can format the HTTP response. Interceptors like ExceptionTranslationFilter wrap access denied exceptions into InsufficientAuthenticationException with default messages such as "Full authentication is required to access this resource". By implementing a custom AuthenticationEntryPoint, these exceptions can be caught and transformed into structured JSON payloads.
public class CustomAuthFailureHandler implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest req, HttpServletResponse res, AuthenticationException authEx) throws IOException {
res.setCharacterEncoding(StandardCharsets.UTF_8.name());
res.setContentType(MediaType.APPLICATION_JSON_VALUE);
ApiResponse payload = new ApiResponse();
payload.setStatus(ResponseStatus.FAILURE);
res.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
if (authEx != null) {
payload.setErrorDetail(authEx.getMessage());
}
if (authEx instanceof InvalidBearerTokenException || authEx instanceof InsufficientAuthenticationException) {
res.setStatus(HttpServletResponse.SC_FAILED_DEPENDENCY); // 424
payload.setMessage("Token has expired");
}
res.getWriter().write(new ObjectMapper().writeValueAsString(payload));
}
}Static Resource Mapping and 404 Resolution
Spring Boot provides default routing for static assets, mapping /** to specific classpath directories: /static, /public, /resources, and /META-INF/resources. The framework searches these locations sequentially to resolve requested resources.
A common 404 NOT FOUND error occurs when replacing static files. If a document format changes (e.g., updating report.doc to report.docx), the newly formatted file must be placed directly into the project directory. Renaming a file internally (e.g., adding temp.docx and renaming it to report.docx) often leads to build inconsistencies and subsequent 404 responses.