Read “SpringBoot + Vue full stack Development” written by Songge, to learn SpringBoot system, the following is a simple shorthand, according to the use of the scene can be quickly located to the knowledge point:

Demo Scaffolding Project Address:

 git clone [email protected]:Vip-Augus/springboot-note.git
Copy the code

Build the project

Instead of using IDEA templates to create projects, I recommend creating projects in one step by selecting parameters on the Spring website

start.spring.io/

All we need to do is modify the organization name and project name, click Generate the project, download it locally, and then open it using IDEA

At this point, clicking the Run method of the Application class directly launches the project without any configuration.


SpringBoot basic configuration

Spring Boot Starters

Quote from Reference 1 Description:

The idea behind starter: Starter includes all the dependencies that are used, avoiding the hassle of having to introduce them themselves. It is important to note that different starter is to solve different dependencies, so their internal implementation may be very different, for example, jPA starter and Redis starter may be implemented differently. That’s because the essence of the starter synthesize is that it’s a logical abstraction, and maybe the idea is a little bit like a Docker, because they’re all doing a wrapper, and if you know what the problem is that Docker solves, Maybe you can draw an analogy between Docker and starter.

One of the concepts that we know is important in SpringBoot is that convention is better than configuration, and by configuring in a certain way, you can reduce many steps to achieve the desired functionality.

For example if we want to use cache Redis

In the past, the following steps may be required:

  1. inpomFiles imported for a specific versionredis
  2. in.propertiesConfigure parameters in the file
  3. Based on the parameters, create one and then anotherjedisThe connection
  4. Define a utility class to manually create a connection pool to manage

After going through the above steps, we can officially use Redis

But in theSpring BootIn, all becauseStartersimple

  1. inpomFile importspring-boot-starter-data-redis
  2. in.propertiesConfigure parameters in the file

Through the above two steps, the configuration takes effect automatically. The specific bean that takes effect is RedisAutoConfiguration. The name of the automatic configuration class has a feature called xxxAutoConfiguration.

Take a quick look at this class:

@Configuration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {

	@Bean
	@ConditionalOnMissingBean(name = "redisTemplate")
	public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
			throws UnknownHostException {
		RedisTemplate<Object, Object> template = new RedisTemplate<>();
		template.setConnectionFactory(redisConnectionFactory);
		return template;
	}

	@Bean
	@ConditionalOnMissingBean
	public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)
			throws UnknownHostException {
		StringRedisTemplate template = new StringRedisTemplate();
		template.setConnectionFactory(redisConnectionFactory);
		returntemplate; }}@ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties {... }Copy the code

As you can see, the Redis auto-configuration class reads the configuration prefixed with Spring. Redis and loads the redisTemplate into the container. Then we can use the redisTemplate to operate on the cache in our application. For example @conditionAlonmissingbean leave a hole (●´∀ ‘●) Blue)

@Autowired
private RedisTemplate redisTemplate;

ValueOperations ops2 = redisTemplate.opsForValue();
Book book = (Book) ops2.get("b1");
Copy the code

@SpringBootApplication

The annotation is on the startup class that loads the project, and it is a composite annotation:

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interfaceSpringBootApplication {... }Copy the code

Here’s an explanation of the three core notes:

Annotation name explain
@SpringBootConfiguration Indicates that this is a configuration class in which developers can configure beans
@EnableAutoConfiguration Indicates that automatic configuration is enabled
@ComponentScan The package scan is complete. The default class to be scanned is located under the package where the current class resides

With this annotation, we implement the mian method:

SpringApplication.run(SpringBootLearnApplication.class, args);
Copy the code

You are ready to launch a Spring Application.


Web Container Configuration

General configuration

The configuration of explain
server.port=8081 The container port number is configured. The default port number is 8080
server.error.path=/error The page to jump to when the project fails is configured
server.servlet.session.timeout=30m Session expiration time. M indicates minutes. If the unit is not specified, the default value is seconds
server.servlet.context-path=/ Project name. If this parameter is not specified, the default value is /. After the configuration, prefix is required for access
server.tomcat.uri-encoding=utf-8 Tomcat request encoding format
server.tomcat.max-threads=500 Maximum number of Tomcat threads
server.tomcat.basedir=/home/tmp If the directory of Tomcat run logs and temporary files is not specified, the system temporary directory is used by default

HTTPS configuration

The configuration of explain
server.ssl.key-store=xxx Secret key file name
server.ssl.key-alias=xxx The secret key alias
server.ssl.key-store-password=123456 The secret key password

To learn more about how to configure HTTPS, you can refer to this article


@ConfigurationProperties

This annotation can be placed on the class or on the @bean annotation method so that SpringBoot can read the configuration of a particular prefix from the configuration file and inject the property value into the corresponding property.

Use examples:

@Configuration
@ConfigurationProperties(prefix = "spring.datasource")
public class DruidConfigBean {

    private Integer initialSize;

    private Integer minIdle;

    private Integer maxActive;
    
    privateList<String> customs; . }Copy the code

application.properties

spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20
spring.datasource.customs=test1,test2,test3
Copy the code

If the object is a list structure, it can be separated by commas in the configuration file, and then injected into the corresponding properties.


Profile

By default, the SpringBoot configuration file name rule is Application -{profile}. Propertie in different environments. The profile placeholder indicates the name of the current environment.

1. Configure application.properties

spring.profiles.active=dev
Copy the code

Add setAdditionalProfiles(“{profile}”) to the main method of the startup class.

SpringApplicationBuilder builder = new SpringApplicationBuilder(SpringBootLearnApplication.class);
builder.application().setAdditionalProfiles("prod");
builder.run(args);
Copy the code

3. Configure startup parameters

java -jar demo.jar --spring.active.profile=dev
Copy the code

@controllerAdvice handles global data

@ControllerAdvice is an enhanced version of @Controller. It is used to process global data and is generally used with @ExceptionHandler, @ModelAttribute, and @initBinder.

@ExceptionHandler Error handling

/** * enhanced controller, intercepting custom exception handling ** /
@ControllerAdvice
public class CustomExceptionHandler {
    
    // Specify the type of exception to be blocked globally
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public void uploadException(MaxUploadSizeExceededException e, HttpServletResponse response) throws IOException {
        response.setContentType("text/html; charset=utf-8");
        PrintWriter out = response.getWriter();
        out.write("Upload file size out of limit"); out.flush(); out.close(); }}Copy the code

@modelAttribute View attributes

@ControllerAdvice
public class CustomModelAttribute {
    
    // 
    @ModelAttribute(value = "info")
    public Map<String, String> userInfo(a) throws IOException {
        Map<String, String> map = new HashMap<>();
        map.put("test"."testInfo");
        returnmap; }}@GetMapping("/hello")
public String hello(Model model) {
    Map<String, Object> map = model.asMap();
    Map<String, String> infoMap = (Map<String, String>) map.get("info");
    return infoMap.get("test");
}
Copy the code
  • key : @ModelAttributeIn the annotationsvalueattribute
  • Usage scenario: Any requestcontrollerClass, through the method parameterModelAll availablevalueCorresponding properties

CORS support, cross-domain resource sharing

Cross-origin Resource Sharing (CORS), cross-domain Resource Sharing technology, the purpose is to solve the front-end cross-domain request.

Reference: When a resource requests a resource from a different domain or port than the server on which the resource itself resides, the resource makes a cross-domain HTTP request

See this article – Implementing Cross-domain Requests (CORS) in the SpringBoot series for more details, but here’s just how to use it:

For example, in my front-end split demo, if Nginx does not forward, the following message will be displayed:

Access to fetch at ‘http://localhost:8888/login’ from origin ‘http://localhost:3000’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: The value of the ‘Access-Control-Allow-Credentials’ header in the response is ” which must be ‘true’ when the request’s credentials mode is ‘include’

To solve this problem, add the following two lines of code to the back end without modifying the front end:

// The first line, the supported domain
@CrossOrigin(origins = "http://localhost:3000")
@RequestMapping(value = "/login", method = RequestMethod.GET)
@ResponseBody
public String login(HttpServletResponse response) {
    // In line 2, the response body adds the header information.
    response.setHeader("Access-Control-Allow-Credentials"."true");
    return HttpRequestUtils.login();
}
Copy the code

Register MVC interceptors

In the MVC module, there are also aOP-like extensions for aspect management that allow for more fine-grained interception handling.

The core is the HandlerInterceptor interface, which is used as follows:

/** * Custom MVC interceptor */
public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Called before the Controller method
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // called after the Controller method
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // after the postHandle method}}Copy the code

Registration Code:

/** * Global control of the MVC configuration */
@Configuration
public class MyWebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor())
                // represents the intercepted URL
                .addPathPatterns("/ * *")
                // Indicates the path to exclude
                .excludePathPatterns("/hello"); }}Copy the code

Interceptor execution order: preHandle -> Controller -> postHandle -> afterCompletion. Note that the method will not proceed until the preHandle method returns true.


Turn on AOP aspect control

Facet injection is a common technique used in Spring. You can refer to the article I wrote before:

Spring custom annotations implement AOP

Spring source learning (eight) AOP use and implementation principle

In SpringBoot, it’s easier to use, just add the dependency and use it the same way as above.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
Copy the code

Integrate Mybatis with Druid

SpringBoot consolidates database operations, while the Druid connection pool and Mybatis persistence layer are currently used in SpringBoot, starter provides a clean solution for consolidations

The project structure is as follows:

Add mybatis and Druid dependencies

 <dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.3.2</version>
</dependency>

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.18</version>
</dependency>
Copy the code

2. Set database and connection pool parameters

#Database Configurationspring.datasource.type=com.alibaba.druid.pool.DruidDataSource Spring. The datasource. The driver - class - name = com. Mysql. Cj. JDBC. Driver spring. The datasource. Url = JDBC: mysql: / / 127.0.0.1:3306 / test? useUnicode=true&characterEncoding=utf8&allowMultiQueries=true spring.datasource.username=root spring.datasource.password=12345678
#Druid configuration
spring.datasource.druid.initial-size=5
spring.datasource.druid.max-active=20
spring.datasource.druid.min-idle=5
spring.datasource.druid.max-wait=60000
spring.datasource.druid.pool-prepared-statements=true
spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20
spring.datasource.druid.max-open-prepared-statements=20
spring.datasource.druid.validation-query=SELECT 1
spring.datasource.druid.validation-query-timeout=30000
spring.datasource.druid.test-on-borrow=true
spring.datasource.druid.test-on-return=false
spring.datasource.druid.test-while-idle=false
#spring.datasource.druid.time-between-eviction-runs-millis=
#spring.datasource.druid.min-evictable-idle-time-millis=
#spring.datasource.druid.max-evictable-idle-time-millis=10000

# Druid stat filter config
spring.datasource.druid.filters=stat,wall
spring.datasource.druid.web-stat-filter.enabled=true
spring.datasource.druid.web-stat-filter.url-pattern=/*
#The session monitoring
spring.datasource.druid.web-stat-filter.session-stat-enable=true
spring.datasource.druid.web-stat-filter.session-stat-max-count=10
spring.datasource.druid.web-stat-filter.principal-session-name=admin
spring.datasource.druid.web-stat-filter.principal-cookie-name=admin
spring.datasource.druid.web-stat-filter.profile-enable=true
# statmonitoring
spring.datasource.druid.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*
spring.datasource.druid.filter.stat.db-type=mysql
spring.datasource.druid.filter.stat.log-slow-sql=true
spring.datasource.druid.filter.stat.slow-sql-millis=1000
spring.datasource.druid.filter.stat.merge-sql=true
spring.datasource.druid.filter.wall.enabled=true
spring.datasource.druid.filter.wall.db-type=mysql
spring.datasource.druid.filter.wall.config.delete-allow=true
spring.datasource.druid.filter.wall.config.drop-table-allow=false

# Druid manage page config
spring.datasource.druid.stat-view-servlet.enabled=true
spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
spring.datasource.druid.stat-view-servlet.reset-enable=true
spring.datasource.druid.stat-view-servlet.login-username=admin
spring.datasource.druid.stat-view-servlet.login-password=admin
#spring.datasource.druid.stat-view-servlet.allow=
#spring.datasource.druid.stat-view-servlet.deny=
spring.datasource.druid.aop-patterns=cn.sevenyuan.demo.*
Copy the code

Other MyBatis configuration

Local project, put the XML file in the Resources folder, so you need to add the following configuration for the application to recognize:

 <build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>/ * * *</include>
            </includes>
        </resource>
    </resources>.</build>
Copy the code

Through the above configuration, I have enabled the monitoring of three pages locally: SQL, URL and Sprint, as shown below:

With the above configuration, SpringBoot can easily integrate Druid and Mybatis, while at the same time integrating with DruidpropertiesThe parameter configured in the file is enabledDruidMonitoring.

However, I cannot enable session monitoring according to the above configuration. Therefore, if you need to configure session monitoring or adjust parameters, you can refer to the official website

alibaba/druid


Integrate Redis

I’ve used Redis and NoSQL, but the one I’m most familiar with and most used is Redis, so here’s how to integrate

First, reference Redis dependency

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <exclusions>
        <exclusion>
            <artifactId>lettuce-core</artifactId>
            <groupId>io.lettuce</groupId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>
Copy the code

2. Parameter configuration

#Redis configuration
spring.redis.database=0
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=
spring.redis.jedis.pool.max-active=8
spring.redis.jedis.pool.max-idle=8
spring.redis.jedis.pool.max-wait=-1ms
spring.redis.jedis.pool.min-idle=0
Copy the code

Three, code use

@Autowired
private RedisTemplate redisTemplate;

@Autowired
private StringRedisTemplate stringRedisTemplate;

@GetMapping("/testRedis")
public Book getForRedis(a) {
    ValueOperations<String, String> ops1 = stringRedisTemplate.opsForValue();
    ops1.set("name"."Go Language Practice");
    String name = ops1.get("name");
    System.out.println(name);
    ValueOperations ops2 = redisTemplate.opsForValue();
    Book book = (Book) ops2.get("b1");
    if (book == null) {
        book = new Book("Go Language Practice".2."none name", BigDecimal.ONE);
        ops2.set("b1", book);
    }
    return book;
}
Copy the code

Spring Data Redis (1) — Parse RedisTemplate


Send an HTML-style message

I’ve used it before, so take a look at this article: Java integrates Spring to send mail

First, introduce dependencies

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

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
Copy the code

2. Configure mailbox parameters

# mail
spring.mail.host=smtp.qq.com
spring.mail.port=465
spring.mail.username=xxxxxxxx
spring.mail.password=xxxxxxxx
spring.mail.default-encoding=UTF-8
spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
spring.mail.properties.mail.debug=true
Copy the code

If you use QQ email, you need to obtain the authorization code from the Settings of the email and fill in the password above

Write templates and send content

MailServiceImpl.java

@Autowired
private JavaMailSender javaMailSender;

@Override
public void sendHtmlMail(String from, String to, String subject, String content) {
    try {
        MimeMessage message = javaMailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message, true);
        helper.setFrom(from);
        helper.setTo(to);
        helper.setSubject(subject);
        helper.setText(content, true);
        javaMailSender.send(message);
    } catch (MessagingException e) {
        System.out.println("Failed to send mail");
        log.error("Failed to send mail", e); }}Copy the code

mailtemplate.html


      
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>mail</title>
</head>
<body>
<div th:text="${subject}"></div>
<div>List of books<table border="1">
        <tr>
            <td>Book number</td>
            <td>The name of the book</td>
            <td>The book the author</td>
        </tr>
        <tr th:each="book:${books}">
            <td th:text="${book.id}"></td>
            <td th:text="${book.name}"></td>
            <td th:text="${book.author}"></td>
        </tr>
    </table>
</div>
</body>
</html>
Copy the code

test.java


@Autowired
private MailService mailService;

@Autowired
private TemplateEngine templateEngine;
    
@Test
public void sendThymeleafMail(a) {
    Context context = new Context();
    context.setVariable("subject"."Book Catalogue");
    List<Book> books = Lists.newArrayList();
    books.add(new Book("Go Language Basics".1."nonename", BigDecimal.TEN));
    books.add(new Book("Go Language Practice".2."nonename", BigDecimal.TEN));
    books.add(new Book("Advanced Go language".3."nonename", BigDecimal.TEN));
    context.setVariable("books", books);
    String mail = templateEngine.process("mailtemplate.html", context);
    mailService.sendHtmlMail("[email protected]"."[email protected]"."Book Catalogue", mail);
}
Copy the code

Through the above simple steps, we can send emails in the code, for example, we need to write weekly reports, statistics system running status, you can set scheduled tasks, statistics, and then send emails automatically.


Integrate Swagger (API Documentation)

First, introduce dependencies

<! -- swagger -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
</dependency>

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.9.2</version>
</dependency>
Copy the code

Configure Swagger parameters

SwaggerConfig.java

@Configuration
@EnableSwagger2
@EnableWebMvc
public class SwaggerConfig {

    @Bean
    Docket docket(a) {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.basePackage("cn.sevenyuan.demo.controller"))
                .paths(PathSelectors.any())
                .build().apiInfo(
                        new ApiInfoBuilder()
                                .description("Spring Boot learn project")
                                .contact(new Contact("JingQ"."https://github.com/vip-augus"."[email protected]"))
                                .version("v1.0")
                                .title("API Test Documentation")
                                .license("Apache2.0")
                                .licenseUrl("http://www.apache.org/licenese/LICENSE-2.0") .build()); }}Copy the code

Setting up the page UI

@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 60)
public class MyWebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");

        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/"); }}Copy the code

By doing this, you can identify @apiOperation and other interface flags, check API documentation on the web page, reference documentation: Spring Boot Combat: integrate Swagger2


conclusion

The integration experience summed up here is only a very basic configuration, in the early stage of learning, grasping the first run, and then constantly improve and progress in learning.

And a single integration is easy, but multiple dependencies can lead to unexpected errors, so when solving environmental problems encountered many pits, want to use basic scaffolding, can try running the project I uploaded.

The database script is in the test.sql file in the Resources directory

At the same time, there are many techniques not summarized in this article. If you want to learn more deeply, please pay attention to “Spring Boot + Vue Full Stack Development” by Songko.


The resources

1. Spring Boot Starters

2. Spring Boot uses SSL-HTTPS

3, Spring Boot (07) — ConfigurationProperties

Implementing Cross-domain Request (CORS) in SpringBoot series

5. Spring Data Redis (1) — Parse RedisTemplate

6, Spring Boot actual combat: integrated Swagger2