Chapter 16 - Spring Boot Flashcards
What is spring boot? main purpose
Spring Boot is a popular framework in the Java ecosystem designed to simplify the process of building and deploying robust, production-ready applications. Its primary purpose is to streamline the development of stand-alone, production-grade applications that are built on the Spring framework.
Here are some key aspects and purposes of Spring Boot:
Simplified Configuration: Spring Boot reduces the need for extensive configuration by providing sensible defaults and auto-configuration. It allows developers to focus more on writing application logic rather than setting up infrastructure.
Embedded Servers: It includes embedded HTTP servers (like Tomcat, Jetty, or Undertow), which means you can run your application as a standalone JAR file without needing to deploy it in a separate web server container.
Dependency Management: It simplifies dependency management by using starter dependencies, which are pre-configured sets of dependencies for specific functionalities (e.g., database, web, security) that can be easily included in your project.
Monitoring and Actuator: Spring Boot Actuator provides production-ready features for monitoring and managing your application. It includes health checks, metrics, info endpoints, etc., which are helpful for monitoring and managing applications in production.
Spring Ecosystem Integration: It seamlessly integrates with the wider Spring ecosystem, enabling easy adoption of other Spring projects like Spring Data, Spring Security, Spring Cloud, etc.
Rapid Development: With its emphasis on convention over configuration, it accelerates the development process by reducing boilerplate code, allowing developers to quickly create applications.
What are the @RequestMapping and @RestController annotation in Spring
Boot used for?
@RequestMapping: This annotation is used at the method level to map web requests to specific handler methods in a controller class. It’s quite versatile and allows you to map HTTP requests (GET, POST, PUT, DELETE, etc.) to specific methods. For instance, you can define the URL path and HTTP method that the method will handle.
@RestController: This annotation is a specialized version of @Controller and is typically used in combination with @RequestMapping. It’s a convenience annotation that combines @Controller and @ResponseBody. When you annotate a class with @RestController, it’s indicating that every method in that class returns a domain object instead of a view. The response is automatically serialized into JSON or XML, depending on the content negotiation settings.
What do you understand by auto-configuration in Spring Boot and how to
disable the auto-configuration?
Auto-configuration in Spring Boot is a powerful feature that aims to reduce the burden of manually configuring your application by providing default configurations based on the dependencies you include in your project’s classpath. It analyzes the environment, classpath, and various other factors to automatically configure beans and settings, making development faster and simpler.
Spring Boot’s auto-configuration works by examining the available beans, properties, and conditions in the environment and then automatically configuring certain components. For instance, if your classpath includes a JDBC library and you haven’t explicitly configured a data source, Spring Boot will configure a default data source using sensible defaults, unless you specify your own.
However, there might be scenarios where you want to disable certain auto-configurations. Here are a few ways to achieve that:
Using @EnableAutoConfiguration with exclusions
You can use @EnableAutoConfiguration annotation in your main class and exclude specific classes or configurations that you want to disable:
java
Copy code
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration;
@SpringBootApplication(exclude = ErrorMvcAutoConfiguration.class)
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
In this example, ErrorMvcAutoConfiguration is being excluded, meaning Spring Boot won’t automatically configure error handling using this configuration.
Using properties to disable auto-configuration
Spring Boot allows you to use properties in your application.properties or application.yml files to disable specific auto-configurations. For example:
properties
Copy code
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
This property disables the default auto-configuration of the data source.
Programmatically disabling specific auto-configuration classes
You can programmatically disable certain auto-configuration classes by excluding them in your SpringApplication:
java
Copy code
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(MyApplication.class);
app.setAdditionalProfiles(“disableDataSource”); // Assuming this profile exists
app.run(args);
}
}
Spring Vs Spring boot
Spring Spring Boot
Spring Framework is a widely used Java EE framework for building applications. Spring Boot Framework is widely used to develop REST APIs.
It aims to simplify Java EE development that makes developers more productive. It aims to shorten the code length and provide the easiest way to develop Web Applications.
The primary feature of the Spring Framework is dependency injection. The primary feature of Spring Boot is Autoconfiguration. It automatically configures the classes based on the requirement.
It helps to make things simpler by allowing us to develop loosely coupled applications. It helps to create a stand-alone application with less configuration.
The developer writes a lot of code (boilerplate code) to do the minimal task. It reduces boilerplate code.
To test the Spring project, we need to set up the sever explicitly. Spring Boot offers embedded server such as Jetty and Tomcat, etc.
It does not provide support for an in-memory database. It offers several plugins for working with an embedded and in-memory database such as H2.
Developers manually define dependencies for the Spring project in pom.xml. Spring Boot comes with the concept of starter in pom.xml file that internally takes care of downloading the dependencies JARs based on Spring Boot Requirement.
What does @SpringBootApplication work?
Here’s what @SpringBootApplication does:
@Configuration: Indicates that the class contains Spring Bean configurations. It allows the class to define beans using @Bean annotations.
@EnableAutoConfiguration: Enables Spring Boot’s auto-configuration feature. It automatically configures the Spring application based on the dependencies present in the classpath. This reduces the need for manual configurations in many cases.
@ComponentScan: Scans for Spring-managed components (such as controllers, services, repositories) within the package and its sub-packages. It discovers and registers these components as Spring Beans.
What is ORM design pattern? How does it work?
Object-Relational Mapping or ORM is a technique for converting data between Java
objects and relational database
Hibernate Framework overview
Hibernate is a framework that simplifies the use of relational databases in Java
applications, by presenting relational data as simple Java objects, otherwise known as
POJOs. These objects are accessed in the program using SessionManager.
Hibernate takes care of the mapping from Java classes to database tables, and from
Java data types to SQL data types. In addition, it provides data query and retrieval
facilities. It can significantly reduce development time otherwise spent with manual data
handling in SQL and JDBC. Hibernate’s design goal is to relieve the developer from
95% of common data persistence-related programming tasks by eliminating the need
for manual, hand-crafted data processing using SQL and JDBC. However, unlike many
other persistence solutions, Hibernate does not hide the power of SQL from you and
guarantees that your investment in relational technology and knowledge is as valid as
always.
Hibernate also provides implementation of Java Persistence API (JPA)
Hibernate and ORM
Hibernate, as an ORM solution, effectively “sits between” the Java application data
access layer and the Relational Database, as can be seen in the diagram above. The
Java application makes use of the Hibernate APIs to load, store, query, etc. its domain
data.
As a Jakarta Persistence provider, Hibernate implements the Java Persistence API
specifications and the association between Jakarta Persistence interfaces and
Hibernate specific implementations can be visualized in the following diagram.
Hibernate and JPA
JPA Hibernate
JPA is described in javax.persistence
package.
Hibernate is described in org.hibernate
package.
It describes the handling of relational
data in Java applications.
Hibernate is an Object-Relational
Mapping (ORM) tool that is used to
save the Java objects in the relational
database system.
It is not an implementation. It is only a
Java specification.
Hibernate is an implementation of JPA.
Hence, the common standard which is
given by JPA is followed by Hibernate.
It is a standard API that permits to
perform database operations.
It is used in mapping Java data types
with SQL data types and database
tables.
As an object-oriented query language, it
uses Java Persistence Query
Language (JPQL) to execute database
operations.
As an object-oriented query language, it
uses Hibernate Query Language
(HQL) to execute database operations.
To interconnect with the entity manager
factory for the persistence unit, it uses
EntityManagerFactory interface. Thus,
it gives an entity manager.
To create Session instances, it uses
SessionFactory interface.
To make, read, and remove actions for
instances of mapped entity classes, it
uses EntityManager interface. This
interface interconnects with the
persistence condition.
To make, read, and remove actions for
instances of mapped entity classes, it
uses Session interface. It acts as a
runtime interface between a Java
application and Hibernate.
Hibernate vs JDBC:
Main advantages of Hibernate over JDBC are as follows: Database Portability: Hibernate can be used with multiple types of database
with easy portability. In JDBC, developer has to write database specific native
queries. These native queries can reduce the database portability of the code.
Connection Pool: Hibernate handles connection pooling very well. JDBC
requires connection pooling to be defined by developer.
Complexity: Hibernate handles complex query scenarios very well with its
internal API like Criteria. So developer need not gain expertise in writing complex
SQL queries. In JDBC application developer writes most of the queries
Hibernate important interfaces
Configuration interface can be implemented in an application to specify the properties
and mapping documents for creating a SessionFactory in Hibernate. By default, a new
instance of Configuration uses properties mentioned in hibernate.properties file.
Configuration is mainly an initialization time object that loads the properties in helps in
creating SessionFactory with these properties. In short, Configuration interface is used
for configuring Hibernate framework in an application.
Configuration: Configuration interface can be implemented in an application to specify
the properties and mapping documents for creating a SessionFactory in Hibernate.
Hibernate application bootstraps by using this interface.
SessionFactory: In Hibernate, SessionFactory is used to create and manage
Sessions. Generally, there is one SessionFactory created for one database. It is a
thread-safe interface that works well in multithreaded applications.
Session: Session is a lightweight object that is used at runtime between a Java
application and Hibernate. It contains methods to create, read and delete operations for
entity classes. It is a basic class that abstracts the concept of persistence.
Transaction: This is an optional interface. It is a short lived object that is used for
encapsulating the overall work based on unit of work design pattern. A Session can
have multiple Transactions.
Query: This interface encapsulates the behavior of an objectoriented query in
Hibernate. It can accept parameters and execute the queries to fetch results. Same
query can be executed multiple times.
Criteria: This is a simplified API to retrieve objects by creating Criterion objects. It is
very easy to use for creating Search like features
SessionFactory Hibernate.
A SessionFactory represents an “instance” of Hibernate: it maintains the runtime
metamodel representing persistent entities, their attributes, their associations, and their
mappings to relational database tables, along with configuration that affects the
runtime behavior of Hibernate, and instances of services that Hibernate needs to
perform its duties.
Crucially, this is where a program comes to obtain sessions. Typically, a program has a
single SessionFactory instance, and must obtain a new Session instance from the
factory each time it services a client request.
Depending on how Hibernate is configured, the SessionFactory itself might be
responsible for the lifecycle of pooled JDBC connections and transactions, or it may
simply act as a client for a connection pool or transaction manager provided by a
container environment.
The internal state of a SessionFactory is considered in some sense “immutable”. While
it interacts with stateful services like JDBC connection pools, such state changes are
never visible to its clients. In particular, the runtime metamodel representing the entities
and their O/R mappings is fixed as soon as the SessionFactory is created. Of course,
any SessionFactory is threadsafe
Session in hibernate
Session is the main runtime interface between a Java application and Hibernate.
Represents the notion of a persistence context, a set of managed entity instances
associated with a logical transaction.
The lifecycle of a Session is bounded by the beginning and end of the logical
transaction. (But a long logical transaction might span several database transactions.)
The primary purpose of the Session is to offer create, read, and delete operations for
instances of mapped entity classes. An instance may be in one of three states with
respect to a given session: transient: never persistent, not associated with any Session, persistent: associated with a unique Session, or detached: previously persistent, not associated with any Se
Hibernate caching. Levels of cache
If you have queries that run over and over, with the same parameters, query caching
provides performance gains.
A Hibernate Session is the first level of cache for persistent data in a transaction.
The second level of cache is at JVM or SessionFactory level.
Caching introduces overhead in the area of transactional processing. For example, if
you cache results of a query against an object, Hibernate needs to keep track of
whether any changes have been committed against the object, and invalidate the cache
accordingly. In addition, the benefit from caching query results is limited, and highly
dependent on the usage patterns of your application. For these reasons, Hibernate
disables the query cache by default.
Hibernate offers two caching levels:
First level cache is enabled by default. It includes the persistence context. Once an
entity gets managed, that object is added to the internal cache of the current
persistence context (EntityManager or Session).
Session merge vs call
The merge() method is used when we want to change a detached entity into the
persistent state again, and it will automatically update the database. The main aim of
the merge() method is to update the changes in the database made by the persistent
object. The merge() method is provided by the Session interface and is available in
org.hibernate.session package.
merge() - Copy the state of the given object onto the persistent object with the same
identifier. If there is no persistent instance currently associated with the session, it will
be loaded. Return the persistent instance. If the given instance is unsaved, save a copy
of and return it as a newly persistent instance. The given instance does not become
associated with the session. This operation cascades to associated instances if the
association is mapped with cascade=”merge