preface

I did some Internet research on Spring Boot the other day and found that there are a lot of interview questions about Spring Boot out there that are completely worthless.

In this article, I will briefly summarize my experience in using Spring Boot in recent years and summarize some common interview questions for you to test and learn. A small number of Spring/Spring Boot introductions refer to the official website, others are original.

This article is the first half, the second half is still being updated, if you want to quickly get the second half of the question, you can directly add Q skirt: 780758112

1. A brief introduction to Spring? What are the disadvantages?

Spring is an alternative to the heavyweight Enterprise development framework Enterprise JavaBean (EJB). Spring provides a relatively simple approach to Enterprise Java development through dependency injection and section-oriented programming, EJB functions are implemented using Plain Old Java Objects (POJOs)

While Spring’s component code is lightweight, its configuration is heavyweight (requiring a lot of XML configuration).

To this end, Spring 2.5 introduces annotation-based component scanning, which eliminates much of the explicit XML configuration for the application’s own components. Spring 3.0 introduces Java-based configuration as a type-safe, reconfigurable alternative to XML.

Still, configuration has not escaped us. Some Spring features, such as transaction management and Spring MVC, still require explicit configuration in XML or Java. Explicit configuration is also required when enabling third-party libraries, such as thymeleaf-based Web views. Configuring servlets and filters (such as Spring’s DispatcherServlet) also requires explicit configuration in web.xml or Servlet initialization code. Component scanning reduces the amount of configuration, and Java configuration makes it look cleaner, but Spring still requires a lot of configuration.

Configuring these XML files is a huge headache and takes up most of our time and energy. On top of that, dependency on related libraries is a pain in the neck, and versioning conflicts between different libraries are common.

2. Why SpringBoot?

Spring is designed to simplify J2EE enterprise application development. Spring Boot F is designed to simplify Spring development (fewer configuration files, out of the box!). .

3. Name the main advantages of using Spring Boot

1. Developing Spring-based applications is easy.

2. A significant reduction in development or engineering time required for Spring Boot projects usually results in higher overall productivity.

3.Spring Boot does not require a lot of boilerplate code, XML configuration, and annotations.

4.Spring boot applications can easily integrate with the Spring ecosystem, such as Spring JDBC, Spring ORM, Spring Data, Spring Security, and more.

5.Spring Boot follows “opinionated defaults” to reduce development effort (defaults can be modified).

6.Spring Boot applications provide embedded HTTP servers, such as Tomcat and Jetty, that make it easy to develop and test Web applications. (This is great! You can run Spring Boot Web projects the way you normally run Java programs.

Spring Boot provides command line interface (CLI) tools for developing and testing Spring Boot applications, such as Java or Groovy.

8.Spring Boot provides a variety of plug-ins that allow you to develop and test Spring Boot applications using built-in tools such as Maven and Gradle.

4. What is Spring Boot Starters?

Spring Boot Starters is a set of dependencies, and with Spring Boot Starters, the project dependencies became much simpler for us.

For example, before Spring Boot Starters, when we were developing REST services or Web applications; We need to use libraries like Spring MVC, Tomcat and Jackson, and these dependencies need to be added manually one by one. However, with Spring Boot Starters we only need a single Spring Boot-starter web dependency, which contains word dependencies that contain all the dependencies we need to develop REST services.

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>

5. What embedded Servlet containers does Spring Boot support?

Spring Boot supports the following embedded Servlet containers:

You can also deploy Spring boot applications into any Servlet 3.1+ compatible Web container.

This is why you can run a SpringBoot project directly like a normal Java project. This really saves a lot of trouble, convenient for us to develop, reduce the difficulty of learning.

6. How do I use Jetty instead of Tomcat in a Spring Boot application?

Spring Boot (spring-boot-starter-web) uses Tomcat as the default embedded servlet container, If you want to use Jetty, just modify Pom.xml (Maven) or build.gradle(gradle).

Maven:

<! -- Exclude Tomcat from Web launcher dependencies --><dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency><! -- Add Jetty dependencies --><dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
Copy the code

Gradle:

compile("org.springframework.boot:spring-boot-starter-web") {
     exclude group: 'org.springframework.boot'.module: 'spring-boot-starter-tomcat'
}
compile("org.springframework.boot:spring-boot-starter-jetty")
Copy the code

As an aside, using Gradle is much cleaner, but Maven is still more commonly used in China. I personally think Gradle is much better in many ways.

7. Introduce the @SpringBootApplication annotation

package org.springframework.boot.autoconfigure;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
        @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
   ......
}
Copy the code
package org.springframework.boot;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {

}
Copy the code

You can see that @SpringBootApplication can be thought of as a collection of @Configuration, @EnableAutoConfiguration, and @ComponentScan annotations. According to The SpringBoot website, the three annotations are:

  • @EnableAutoConfiguration: Enables SpringBoot automatic configuration
  • @ComponentScan: scans beans annotated by @Component (@service,@Controller). By default, the annotation scans all classes in the package in which that class belongs.
  • @Configuration: allows registering additional beans or importing additional configuration classes in the context

8. How is automatic configuration of Spring Boot implemented?

This is due to the @SpringBootApplication annotation, which was mentioned in the previous question. We know that @SpringBootApplication is considered a collection of @Configuration, @EnableAutoConfiguration, and @ComponentScan annotations.

– @enableAutoConfiguration: enables the automatic configuration mechanism of SpringBoot

  • @ComponentScan: scan be@Component (@Service.@ControllerAnnotated beans, which by default scan all classes in the package that class is in.
  • @Configuration: allows registering additional beans or importing additional configuration classes in the context

@enableAutoConfiguration is the key to start automatic configuration, the source code is as follows (suggest their own interrupt point debugging, go through the basic process) :

import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.context.annotation.Import; @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import({AutoConfigurationImportSelector.class}) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class<? >[] exclude() default {}; String[] excludeName() default {}; }Copy the code

@ EnableAutoConfiguration annotations by Spring provides @ Import annotations into AutoConfigurationImportSelector class (@ Import annotations can Import the configuration class or Bean to the current class).

All AutoConfigurationImportSelector getCandidateConfigurations method in class will automatically configure class information in the form of a List of the return. This configuration information is managed by the Spring container as beans.

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
    List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
            getBeanClassLoader());
    Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
            + "are using a custom packaging, make sure that file is correct.");
    return configurations;
}
Copy the code

Autoconfiguration information is available, so what’s left for autoconfiguration?

@ Conditional annotation. ConditionalOnClass(the specified class must exist under the classpath), ConditionalOnBean(whether the specified Bean is in the container) and so on are extensions of the @conditional annotation.

With Spring Security automatic configuration, for example: SecurityAutoConfiguration import WebSecurityEnablerConfiguration in class, WebSecurityEnablerConfiguration source code is as follows:

@ConditionalOnBean(WebSecurityConfigurerAdapter.class)
@ConditionalOnMissingBean(name = BeanIds.SPRING_SECURITY_FILTER_CHAIN)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@EnableWebSecurity
public class WebSecurityEnablerConfiguration {



}
Copy the code

WebSecurityEnablerConfiguration class using the @ ConditionalOnBean specifies the container must have WebSecurityConfigurerAdapter class or its implementation class. So, the Spring Security configuration class will usually be able to achieve WebSecurityConfigurerAdapter, it automatically configuration is done.

9. What are common annotations used to develop RESTful Web services?

Spring Bean related:

  • @Autowired : Automatically imports objects into classes. The injected classes are also managed by the Spring container.

– @RestController : The @RestController annotation is a combination of @Controller and @responseBody, indicating that this is a Controller bean and that the return value of the function is inserted directly into the body of the HTTP response, which is a REST-style Controller.

  • @Component : Generic annotations to annotate any class as a Spring component. This can be used if a Bean does not know which layer it belongs to@Component Annotation annotation.
  • @Repository : Corresponds to the Dao layer, which is mainly used for database operations.
  • @Service : Corresponds to the service layer, which mainly involves some complex logic and requires the Dao layer.
  • @Controller: Corresponds to the Spring MVC control layer, which is mainly used to accept user requests and call the Service layer to return data to the front-end page.

Handling common HTTP request types:

  • @GetMapping: GET request,
  • @PostMapping: POST request.
  • @PutMapping : PUT Request.
  • @DeleteMapping: DELETE request.

Front and back end values:

  • @requestParam and @PathVairable: @pathVariable is used to get path parameters, and @requestParam is used to get query parameters.
  • @ RequestBody: It is used to read the body of a Request (POST,PUT,DELETE,GET) and its content-type is in application/ JSON format. After receiving the data, it will automatically bind the data to a Java object. The system uses HttpMessageConverter or a custom HttpMessageConverter to convert the JSON string in the body of the request into a Java object.

10. Two common configuration files for Spirng Boot

You can simply configure the Spring Boot program using application.properties or application.yml. If you do not configure it, the default configuration is used.

11. What is YAML? What are the advantages of YAML configurations?

YAML is a human-readable data serialization language. It is usually used for configuration files. Compared to properties files, YAML files are more structured and less confusing if we want to add complex properties to a configuration file. You can see that YAML has hierarchical configuration data.

Compared to Properties configuration, YAML configuration is more intuitive, concise, and hierarchical.

However, one disadvantage of the YAML configuration approach is that the @propertysource annotation does not support importing custom YAML configurations.

12. What are the common methods used by Spring Boot to read configuration files?

The application. Yml configuration file we will read reads as follows:

wuhan2020: 2020There was a novel coronavirus outbreak in Wuhan at the beginning of the year, but I'm sure everything will pass! Come on, Wuhan! Come on China! My-profile: name: Java peachemail: koushuangbwcx@163.com

libraryCome on, Go Chinabooks: -name: Genius Basic LawdescriptionOn the day that his father was diagnosed with Alzheimer's disease, Lin Zhaoxi, 22, learned that pei Zhi, the campus boy he had loved for years, was going abroad for further study -- the same school his father had given up for her. - name: indicates the time orderdescription: Why do we remember the past, not the future? What does it mean for time to "go by"? Do we exist within time, or does time exist within us? In poetic prose, Carlo Rovelli invites us to consider this age-old conundrum: the nature of time. - name: Great medescription: How to form a new habit? How to let the mind become more mature? How to have quality relationships? How do you get through tough times in your life?Copy the code

12.1. Read simple configuration information through @value

Use @value (“${property}”) to read simpler configuration information:

@Value("${wuhan2020}") String wuhan2020;

Note that @value is not recommended. Spring recommends the following ways to read configuration information.

12.2. Read and bind to the bean via @ConfigurationProperties

The @Component annotation is added to the LibraryProperties class, which can be injected into the class just like a normal bean.

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
@ConfigurationProperties(prefix = "library")
@Setter
@Getter
@ToString
class LibraryProperties {
    private String location;
    private List<Book> books;

    @Setter
    @Getter
    @ToString
    static class Book {
        String name;
        Stringdescription; }}Copy the code

At this point you can inject it into the class just as you would with a normal bean:

package cn.javaguide.readconfigproperties;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/ * * *@author shuang.kou
 */
@SpringBootApplication
public class ReadConfigPropertiesApplication implements InitializingBean {

    private final LibraryProperties library;

    public ReadConfigPropertiesApplication(LibraryProperties library) {
        this.library = library;
    }

    public static void main(String[] args) {
        SpringApplication.run(ReadConfigPropertiesApplication.class, args);
    }

    @Override
    public void afterPropertiesSet(){ System.out.println(library.getLocation()); System.out.println(library.getBooks()); }}Copy the code

Console output:

[LibraryProperties.Book(name= Genius Basic Law, description........]Copy the code

12.3. Read and verify with @configurationProperties

Let’s change application.yml to the following, which clearly shows that this is not the correct email format:

My-profile: name: Java peachemail: koushuangbwcx@
Copy the code

The ProfileProperties class has no @Component annotation. Us where we want to use ProfileProperties use @ EnableConfigurationProperties register our configuration bean:

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;

/ * * *@author shuang.kou
*/
@Getter
@Setter
@ToString
@ConfigurationProperties("my-profile")
@Validated
public class ProfileProperties {
   @NotEmpty
   private String name;

   @Email
   @NotEmpty
   private String email;

   // If the configuration file is not read, use the default value
   private Boolean handsome = Boolean.TRUE;

}
Copy the code

Specific use:

package cn.javaguide.readconfigproperties;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;

/ * * *@author shuang.kou
 */
@SpringBootApplication
@EnableConfigurationProperties(ProfileProperties.class)
public class ReadConfigPropertiesApplication implements InitializingBean {
    private final ProfileProperties profileProperties;

    public ReadConfigPropertiesApplication(ProfileProperties profileProperties) {
        this.profileProperties = profileProperties;
    }

    public static void main(String[] args) {
        SpringApplication.run(ReadConfigPropertiesApplication.class, args);
    }

    @Override
    public void afterPropertiesSet(){ System.out.println(profileProperties.toString()); }}Copy the code

Because the format of our mailbox is not correct, so when the program runs, the error will be reported, which can not run at all, to ensure the security of the data type:

Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'my-profile' to cn.javaguide.readconfigproperties.ProfileProperties failed:

    Property: my-profile.email
    Value: koushuangbwcx@
    Origin: class path resource [application.yml] : 5:10Reason: must be a well-formed email address
Copy the code

If we change the mailbox test to correct and run it again, the console will successfully print the read message:

ProfileProperties(Name = Java Peach, email= Koushuangbwcx@163.com, handsome=true)
Copy the code

12.4.@propertysource Reads the specified properties file

import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

@Component
@PropertySource("classpath:website.properties")
@Getter
@Setter
class WebSite {
    @Value("${url}")
    private String url;
}
Copy the code

Use:

@Autowired
private WebSite webSite;

System.out.println(webSite.getUrl());//https://javaguide.cn/
Copy the code