Gradle is a powerful and flexible build automation system that uses a Groovy-based DSL (Domain Specific Language) or Kotlin-based DSL for defining build tasks. It was designed to overcome the shortcomings of Apache Ant and Apache Maven, and it is widely adopted in the Java community, as well as in Android app development.
Here’s a breakdown of Gradle’s key features and how it works:
build.gradle.gradlew on UNIX-like systems or gradlew.bat on Windows). This is a small script that can download and install the correct version of Gradle for a project, ensuring consistent builds across different environments.How does it work?
Gradle is a versatile tool that can be used not only for Java projects but also for C++, Python, and more. It has integrations with many IDEs (like IntelliJ IDEA and Android Studio) and CI/CD tools, making it a popular choice for modern development environments.
How to run tests using gradle?
in maven -> mvn test
gradle test or ./gradlew test
How to compile java project using gradle?
in maven -> mvn compile
gradle compileJava or ./gradlew compileJava
How to package a springboot project using gradle?
in maven -> mvn package
gradle jar or ./gradlew jar
How to skip tests using gradle?
in maven -> mvn install -DskipTests
gradle assemble -x test or ./gradlew assemble -x test
How to list dependencies using gradle?
in maven -> mvn dependency:list
gradle dependencies or ./gradlew dependencies
Including a dependency in a Gradle project with Spring Boot typically involves adding the dependency to the build.gradle file. Here’s a step-by-step process:
Ensure You Have the Spring Boot Gradle Plugin:
First, make sure your build.gradle file applies the Spring Boot Gradle plugin and has the Spring Boot dependencies’ BOM (Bill Of Materials):
plugins {
id 'org.springframework.boot' version '2.5.4' // Use the appropriate version
id 'io.spring.dependency-management' version '1.0.11.RELEASE' // Again, ensure the version matches your needs
id 'java'
}
Include the Spring Boot Repositories (if not already added):
Spring Boot dependencies are available in the Maven Central repository, but if you’re using Spring Milestone or Snapshot releases, you might also need the Spring repositories:
repositories {
mavenCentral()
// For milestone releases
maven { url 'https://repo.spring.io/milestone' }
// For snapshots
maven { url 'https://repo.spring.io/snapshot' }
}
Add Your Dependency:
Let’s say you want to include Spring Web to create a web application. You would add:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
// ... your other dependencies
}
Note:
implementation is a configuration indicating that the dependency is required for compiling the source code of the module and is also required at runtime.'group:artifact:version', but when using the Spring Boot BOM, you often don’t need to specify the version since it’s managed by Spring Boot’s dependency management.
Refresh Your Dependencies:
If you’re using an IDE like IntelliJ IDEA or Eclipse, you might need to refresh your project to download the new dependencies. For command-line builds, the next time you run a Gradle task like ./gradlew bootRun, the dependencies will be fetched automatically.
Additional Tip:
To view all the managed versions and dependencies provided by Spring Boot, you can check the spring-boot-dependencies BOM in the Maven Central repository. It’s a useful reference when you want to know the default versions for various libraries that Spring Boot manages.
Remember, the versions and dependencies might vary based on the specific version of Spring Boot you’re using, so always refer to the official Spring Boot documentation or the Spring Initializr website for accurate information.
In a standard application without dependency injection, components and services often create or look up their dependencies. This creates tight coupling between components and makes them harder to test or reuse. With DI, components declare their dependencies (typically via constructor arguments, properties, or annotations), and a container or framework (like Spring) provides those dependencies. This helps in:
@Service
public class OrderService {
private final UserRepository userRepository;
@Autowired
public OrderService(UserRepository userRepository) {
this.userRepository = userRepository;
}
// Other methods
}
Note: In modern Spring versions, if a class has a single constructor, the @Autowired annotation can be omitted, and Spring will use that constructor by default.
@Service
public class OrderService {
private UserRepository userRepository;
@Autowired
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
// Other methods
}
@Service
public class OrderService {
@Autowired
private UserRepository userRepository;
// Other methods
}
@Qualifier annotation.
@Service
public class OrderService {
private final DataSource dataSource;
@Autowired
public OrderService(@Qualifier("mainDataSource") DataSource dataSource) {
this.dataSource = dataSource;
}
// Other methods
}
Car) object that creates its own engine (Engine) instance.
public class Engine {
public void start() {
// Start engine
}
}
public class Car {
private Engine engine;
public Car() {
this.engine = new Engine();
}
}
In the example above, the Car class is tightly coupled to a specific Engine. This makes it challenging to replace Engine with a different implementation or to mock the engine during testing.
public class Car {
private Engine engine;
public Car(Engine engine) {
this.engine = engine;
}
}
Here, the Car doesn’t create its Engine. Instead, it’s supplied with an engine. This makes it possible to provide different engine implementations or mock engines for testing.
<!-- Spring XML Configuration -->
<bean id="engine" class="com.example.Engine" />
<bean id="car" class="com.example.Car">
<constructor-arg ref="engine"/>
</bean>
@Component
public class Engine {
@PostConstruct
public void initialize() {
// Initialization code
}
@PreDestroy
public void cleanup() {
// Cleanup code
}
}
In essence, IoC flips the traditional flow of control. Instead of objects controlling their own dependencies, a container or framework takes on the responsibility. This inversion leads to software that’s more modular, easier to test, and more resilient to change.
Here, the initialize method is called after the Engine bean is created, and cleanup is called before it’s destroyed.
The IoC container receives metadata from XML files, annotations, or Java configuration classes, and then uses this metadata to create and manage the lifecycle of the beans. The main tasks of the IoC container are:
There are two primary types of IoC containers in Spring:
BeanFactory. It provides additional features such as event propagation, declarative mechanisms to create a bean, integration with AOP (Aspect-Oriented Programming), and more. In most Spring-based applications (including Spring Boot apps), ApplicationContext is used more often than BeanFactory.Spring Boot simplifies the use of the IoC container by eliminating most of the boilerplate configuration. With features like auto-configuration and component scanning, Spring Boot makes it easier to create, wire, and manage beans with minimal explicit configuration.
@Component
public class HelloWorld {
public String sayHello() {
return "Hello, World!";
}
}
@Service
public class MessageService {
private final HelloWorld helloWorld;
@Autowired
public MessageService(HelloWorld helloWorld) {
this.helloWorld = helloWorld;
}
public void showMessage() {
System.out.println(helloWorld.sayHello());
}
}
@SpringBootApplication
public class MyApp {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(MyApp.class, args);
MessageService messageService = context.getBean(MessageService.class);
messageService.showMessage();
}
}
@SpringBootApplication annotation?@Configuration, @EnableAutoConfiguration, and @ComponentScan.banner.txt file in the src/main/resources directory or setting a banner.location property.@Value annotation or by injecting the Environment object.application.properties and application.yml:
src/main/resources).application-dev.properties for a dev profile).application.propertiesapplication.properties or application.yml in the jar (lowest precedence).SPRING_DATASOURCE_URL would map to the spring.datasource.url property in the application.@Value Annotation:
@Value("${property.name}") annotation.
@Value("${custom.property}")
private String customProperty;
@Value annotation, you can bind properties to POJOs annotated with @ConfigurationProperties. This method is type-safe and offers additional benefits like validation and code-completion in IDEs.
@ConfigurationProperties(prefix="custom")
public class CustomProperties {
private String property;
// getters and setters
}
${another.property}).spring.datasource.url, spring.datasource-url, SPRING_DATASOURCE_URL, and spring.datasource_url would all match the spring.datasource.url property.spring.profiles.active property (e.g., in application.properties or as a command-line argument).SPRING_PROFILES_ACTIVE environment variable.SpringApplication.setAdditionalProfiles(...) method programmatically.application-dev.properties will only be applied when the dev profile is active.application-dev.yml.@Profile annotation:
@Profile("dev")
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder().build();
}
cloud profile that’s used for any cloud provider and a aws profile that’s specific to AWS. You can activate both profiles simultaneously.default profile will be used.@Profile("!prod")
@Bean
public DataSource dataSource() {
// This bean will be created when the 'prod' profile is NOT active
}
java -jar myapp.jar --spring.profiles.active=prod
spring.profiles.active property./health, /info, /metrics, /env.@EntityScan?SpringApplication.run() method.server.* properties (e.g., server.port).@RepositoryRestResource?spring-boot-starter-aop.application.properties or application.yml.@RestController vs @Controller.@RestController is a shorthand for @Controller + @ResponseBody.@EnableTransactionManagement and by using @Transactional on methods.@ControllerAdvice and @ExceptionHandler.spring-boot-starter-test with utilities like MockMvc.spring-boot-maven-plugin.@ComponentScan(excludeFilters = @Filter).application.properties?spring.config.location property.server.port in application.properties.@ConditionalIt indicates a component is only eligible for registration when a specific condition matches.@SpringBootTest?SpringApplication and loads all registered beans.@SpringBootTest is an annotation provided by Spring Boot that is used for integration testing. It helps to bootstrap the entire container (depending on the provided configuration), so you can test the application in scenarios close to the actual use.Features of @SpringBootTest:
Examples of using @SpringBootTest:
@SpringBootTest
class MyApplicationTests {
@Test
void contextLoads() {
}
}
This test ensures that the application context loads without any issues.
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class MyWebApplicationTests {
@Autowired
TestRestTemplate restTemplate;
@Test
void testHomeEndpoint() {
String response = restTemplate.getForObject("/", String.class);
assertEquals("Hello World", response);
}
}
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
class MyWebMockTest {
@Autowired
MockMvc mockMvc;
@Test
void testEndpoint() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/"))
.andExpect(status().isOk())
.andExpect(content().string("Hello World"));
}
}
@SpringBootTest(properties = {"custom.property=value"})
class PropertyOverrideTest {
//...
}
@ActiveProfiles: To activate certain profiles during testing, you can combine it with @ActiveProfiles:
@SpringBootTest
@ActiveProfiles("test")
class MyProfileTest {
//...
}
The @SpringBootTest annotation simplifies integration testing for Spring Boot applications by setting up and tearing down the application context and providing various utilities and configurations specific to the testing phase.
35. How can you serve static content in Spring Boot?
/public, /resources, /static, or /META-INF/resources directories.By default, Spring Boot serves static content from the following locations inside your project:
/META-INF/resources//resources//static//public/For instance, if you place an index.html file inside the src/main/resources/static/ directory of your Spring Boot application, you can access it by visiting http://localhost:8080/index.html after starting your application.
If you want to customize the static content locations, you can do so by configuring the spring.resources.static-locations property. For example, to serve static content from a custom-dir directory:
spring.resources.static-locations=classpath:/custom-dir/
36. Describe the hierarchy of application.properties in Spring Boot.
@TestPropertySource, @SpringBootTest.properties, and inside the JAR are examples of levels.
In Spring Boot, the application.properties (or its YAML counterpart, application.yml) file is the primary means for configuring application settings. Spring Boot provides a flexible system of looking for this configuration file in various locations and offers a hierarchy that determines the order of precedence for reading these configurations.
Here’s the hierarchy for application.properties locations, starting from the highest precedence:
java -jar app.jar --server.port=8081SPRING_APPLICATION_JSON:
SPRING_APPLICATION_JSON environment variable.-D argument, e.g., java -Dserver.port=8081 -jar app.jarserver.port can be sourced from an environment variable named SERVER_PORT.application.properties or application.yml located in the same directory from which the application is run../config sub-directory of the directory from which the application is run.application.properties or application.yml at the root of the classpath, typically inside the src/main/resources directory./config package or directory inside the jar.application.properties or application.yml located in the classpath root.SpringApplication.setDefaultProperties.Profile-specific properties:
Along with the above, Spring Boot allows for profile-specific property files. These are named like application-{profile}.properties or application-{profile}.yml. Profile-specific property files have precedence over the default application.properties or application.yml but are ordered by the same precedence rules mentioned above.
For example, if a dev profile is active, application-dev.properties outside the jar will override the application.properties outside the jar, but both will be overridden by any value passed as a command-line argument.
Conclusion: The hierarchy and the ability to source configurations from various locations allow for a high degree of flexibility. You can have default settings packaged within your application and override them for different environments using external files or even command-line arguments. This makes it easier to manage configurations across different deployment scenarios without changing the packaged application.
37. What is a Spring Boot Fat JAR?
38. What are the main advantages of using Spring Boot?
39. How do you enable debug logging in Spring Boot?
logging.level.root=DEBUG in application.properties.40. Explain the importance of the pom.xml file in Spring Boot.
41. What’s the purpose of @EnableAutoConfiguration?
42. How does Spring Boot simplify database connectivity?
spring-boot-starter-data-jpa.application.properties or application.yml files.spring.datasource.url, spring.datasource.username, and spring.datasource.password, you can configure a data source without any manual bean definitions.
spring.datasource.url=jdbc:mysql://localhost:3306/mydb spring.datasource.username=root spring.datasource.password=secret
spring.datasource.hikari.maximum-pool-size=10
EntityManager.CrudRepository or JpaRepository and Spring Boot automatically provides the implementation at runtime, enabling CRUD operations on entities without writing the boilerplate code.schema.sql and data.sql) and run them at startup to initialize the database.schema.sql in the src/main/resources directory, Spring Boot will execute it on startup.schema.sql:application-{profile}.properties files can be used for different environments. This means you can have separate configurations for development, staging, and production, making it easy to switch between databases based on the active profile.JdbcTemplate, making it easier to interact with relational databases without managing connections and exceptions manually.
@Autowired
JdbcTemplate jdbcTemplate;
public int getCountOfBooks() {
return jdbcTemplate.queryForObject("SELECT COUNT(*) FROM book", Integer.class);
}
DataAccessException, making it easier to handle database-related errors in a consistent way.In essence, Spring Boot removes much of the boilerplate code traditionally associated with setting up and managing database connections in a Spring application. This allows developers to focus on their domain logic rather than the intricacies of database setup and connectivity.43. What is the importance of @Repository in Spring Boot?
44. How can you specify the active profile while running a Spring Boot application?
--spring.profiles.active=myprofile during startup.45. How can you secure a Spring Boot application?
spring-boot-starter-security and @EnableWebSecurity.First and foremost, you’ll need to add the Spring Security starter to your pom.xml (if using Maven):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
By merely including the above dependency, Spring Boot will set up basic authentication for all routes with a default user named “user” and a generated password that’s displayed in the console on startup.
Example: Accessing any endpoint without authentication will return a 401 Unauthorized. Use the provided username and password in the request header or when prompted by the browser to authenticate.
You can configure user details and their roles in memory or retrieve them from a database.
Example – In-memory Authentication:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin").password("{noop}admin123").roles("ADMIN")
.and()
.withUser("user").password("{noop}user123").roles("USER");
}
}
You can specify which routes or endpoints are accessible by which roles.
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasAnyRole("ADMIN", "USER")
.antMatchers("/").permitAll()
.and().formLogin();
}
46. What is a CommandLineRunner in Spring Boot?
47. Describe the structure of a typical Spring Boot project.
src/main/java and resources in src/main/resources.48. How can you customize the Jackson ObjectMapper in Spring Boot?
@Bean of type ObjectMapper in a configuration class.49. What are the benefits of using the Spring Boot DevTools?
50. What is spring-boot-starter-parent?
Spring framework has a retry project that is very useful when you have a business logic failure that you want to be able to retry to complete.
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
@Configuration
@EnableRetry
public class GlobalConfig {
}
@Service
@Slf4j
public class UserServiceImp implements UserService {
@Retryable(value = {RuntimeException.class}, maxAttempts = 3, backoff = @Backoff(delay = 2000))
@Override
public boolean sendEmail(User user) throws RuntimeException {
log.info("send email");
if (true) {
throw new RuntimeException("error");
}
return false;
}
@Recover
@Override
public boolean recover(RuntimeException e, User user) {
log.info("recover");
return true;
}
}
Project Lombok is a java library that automatically plugs into your editor and build tools, spicing up your java.
Never write another getter or equals method again, with one annotation your class has a fully featured builder, Automate your logging variables, and much more.
Java can get too verbose for things you have to do such as generating getter and setter methods. These things often bring no real value to the business side of your applications. This is what lombok is for. Lombok is here to help you generate boilerplate code and you focus on business logic. The way it works is by plugging into your build process and autogenerating Java bytecode into your .class files as per a number of project annotations you introduce in your code.
Install Lombok on your computer
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>



Use Lombok in your project
import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.Lob;
import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotEmpty;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.ResultCheckStyle;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.UpdateTimestamp;
import org.hibernate.annotations.Where;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.social.api.address.Address;
import com.social.api.user.role.Role;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@Setter
@Getter
@ToString
@AllArgsConstructor
@NoArgsConstructor
@JsonInclude(value = Include.NON_NULL)
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String firstName;
private String lastName;
private String email;
private String password;
private String phoneNumber;
private Date dateOfBirth;
private String aboutMe;
private String profileImageUrl;
private String coverImageUrl;
private Date passwordExpirationDate;
private Integer invalidPasswordCounter = 0;
}
Create auth server and resource server
Create auth client that consumes resource from a third party like Google or Github