Demo Scaffolding Project Address:

Github.com/Vip-Augus/s…

Table of Contents

generated with DocToc

  • SpringBoot shorthand

  • First, introduce dependencies

  • Configure Swagger parameters

  • First, introduce dependencies

  • 2. Configure mailbox parameters

  • Write templates and send content

  • First, reference Redis dependency

  • 2. Parameter configuration

  • Three, code use

  • Add mybatis and Druid dependencies

  • 2. Set database and connection pool parameters

  • Other MyBatis configuration

  • @ExceptionHandler Error handling

  • @modelAttribute View attributes

  • General configuration

  • HTTPS configuration

  • Build the project

  • SpringBoot basic configuration

  • Spring Boot Starters

  • @SpringBootApplication

  • Web Container Configuration

  • @ConfigurationProperties

  • Profile

  • @controllerAdvice handles global data

  • CORS support, cross-domain resource sharing

  • Register MVC interceptors

  • Turn on AOP aspect control

  • Integrate Mybatis with Druid

  • Integrate Redis

  • Send an HTML-style message

  • Integrate Swagger (API Documentation)

  • conclusion

  • The resources

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. Introduce a specific version of Redis into poM files

  2. Configure the parameters in the.properties file

  3. Create one jedis connection after another based on the parameters

  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 Spring Boot, everything is made easier by Starter

  1. Introduce spring-boot-starter-data-redis in the POM file

  2. Configure the parameters in the.properties 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); return template; }}@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)

@Autowiredprivate 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 @interface SpringBootApplication {... }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;        private List<String> customs;        ...}application.propertiesspring.datasource.initialSize=5spring.datasource.minIdle=5spring.datasource.maxActive=20spring.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

@controllerAdvicePublic Class CustomExceptionHandler {// Specify the exception type to be handled globally. Unified handling @ 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 exceeds limit "); out.flush(); out.close(); }}Copy the code

@modelAttribute View attributes

@ControllerAdvicepublic class CustomModelAttribute { // @ModelAttribute(value = "info") public Map<String, String> userInfo() throws IOException { Map<String, String> map = new HashMap<>(); map.put("test", "testInfo"); return map; }}@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: @modelAttribute The value attribute in the annotation

  • Usage scenario: Any request controller class, through the method parameters in the Model can obtain the value of the corresponding attribute

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 the at “http://localhost:8888/login” from origin “http://localhost:3000” has had 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, Supported domains @crossorigin (origins = "http://localhost:3000") @requestMapping (value = "/login", Method = requestmethod.get) @responseBodyPublic String login(HttpServletResponse Response) { Responsetheader (" access-Control-allow-credentials ", "true"); 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:

/** * public class MyInterceptor implements HandlerInterceptor {@override public Boolean preHandle(HttpServletRequest request, HttpServletResponse response, Throws Exception {// Call return true before the Controller method; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView ModelAndView) throws Exception {// Called after controller method} @override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Throws Exception {// call after the postHandle method}}Copy the code

Registration Code:

/ / @implements WebMvcConfigurer {@override public void implements WebMvcConfigurer AddInterceptors (InterceptorRegistry registry) {registry. AddInterceptor (new MyInterceptor()) // Represents the intercepting URL .addPathPatterns("/**") // shows paths that need to be excluded. 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 > < the dependency > < groupId > com. Alibaba < / groupId > < artifactId > druid - spring - the boot - starter < / artifactId > < version > 1.1.18 < / version > < / dependency >Copy the code

2. Set database and connection pool parameters

# Database configuration spring. The datasource. Type = com. Alibaba. Druid. Pool. DruidDataSourcespring. The datasource. Driver - class - name = com. Mysql. Cj. JDBC. Driverspring. The datasource. Url = JDBC: mysql: / / 127.0.0.1:3306 / test? useUnicode=true&characterEncoding=utf8&allowMultiQueries=truespring.datasource.username=rootspring.datasource.password=1 2345678# druid Configure spring. The datasource. The druid. Initial - size = 5 spring. The datasource. The druid. Max - active = 20 spring. The datasource. The druid. Min - idle = 5 spring. Da tasource.druid.max-wait=60000spring.datasource.druid.pool-prepared-statements=truespring.datasource.druid.max-pool-prepa red-statement-per-connection-size=20spring.datasource.druid.max-open-prepared-statements=20spring.datasource.druid.valid ation-query=SELECT 1spring.datasource.druid.validation-query-timeout=30000spring.datasource.druid.test-on-borrow=truespring.datasource.drui d.test-on-return=falsespring.datasource.druid.test-while-idle=false#spring.datasource.druid.time-between-eviction-runs-m illis=#spring.datasource.druid.min-evictable-idle-time-millis=#spring.datasource.druid.max-evictable-idle-time-millis=10 000# Druid stat filter configspring.datasource.druid.filters=stat,wallspring.datasource.druid.web-stat-filter.enabled=truespring.datasource.dru id.web-stat-filter.url-pattern=/*# session Monitoring the spring. The datasource. The druid. Web - stat - filter. The session - stat - enable = truespring. The datasource. The druid. Web - stat - filter. The session - stat - m ax-count=10spring.datasource.druid.web-stat-filter.principal-session-name=adminspring.datasource.druid.web-stat-filter.p rincipal-cookie-name=adminspring.datasource.druid.web-stat-filter.profile-enable=true# stat Monitoring spring. The datasource. The druid. Web - stat - filter. Exclusions = *. Js, *. GIF,. *, *. *. BMP, JPG PNG, *. CSS, *. Ico, / druid / * spring in the datasource. druid.filter.stat.db-type=mysqlspring.datasource.druid.filter.stat.log-slow-sql=truespring.datasource.druid.filter.stat. slow-sql-millis=1000spring.datasource.druid.filter.stat.merge-sql=truespring.datasource.druid.filter.wall.enabled=truesp ring.datasource.druid.filter.wall.db-type=mysqlspring.datasource.druid.filter.wall.config.delete-allow=truespring.dataso urce.druid.filter.wall.config.drop-table-allow=false# Druid manage page configspring.datasource.druid.stat-view-servlet.enabled=truespring.datasource.druid.stat-view-servlet.url-pattern=/druid /*spring.datasource.druid.stat-view-servlet.reset-enable=truespring.datasource.druid.stat-view-servlet.login-username=ad minspring.datasource.druid.stat-view-servlet.login-password=admin#spring.datasource.druid.stat-view-servlet.allow=#sprin g.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 this configuration, SpringBoot can easily integrate Druid with Mybatis, and enable Druid monitoring according to the parameters configured in the properties file.

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

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 Configure spring. Redis. Database = 0 spring. Redis. Host = localhostspring. Redis. Port = 6379 spring. Redis. Password = spring. Redis. Jedis. The pool. max-active=8spring.redis.jedis.pool.max-idle=8spring.redis.jedis.pool.max-wait=-1msspring.redis.jedis.pool.min-idle=0Copy the code

Three, code use

@Autowiredprivate RedisTemplate redisTemplate; @Autowiredprivate StringRedisTemplate stringRedisTemplate; @GetMapping("/testRedis")public Book getForRedis() { ValueOperations<String, String> ops1 = stringRedisTemplate.opsForValue(); Ops1. set("name", "Go "); 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 ", 2, "None name", BigDecimal.ONE); ops2.set("b1", book); } return book; }Copy the code

Here is just a simple record of reference and usage, more functions can be seen here:

Send an HTML-style message

It’s been used before, so check out this article:

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

# mailspring.mail.host=smtp.qq.comspring.mail.port=465spring.mail.username=xxxxxxxxspring.mail.password=xxxxxxxxspring.mai l.default-encoding=UTF-8spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactoryspring.mail.p roperties.mail.debug=trueCopy 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@Autowiredprivate JavaMailSender javaMailSender; @Overridepublic 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 email "); Log.error (" Failed to send mail ", e); }}mailtemplate.html<! DOCTYPE html><html lang="en" xmlns:th="http://www.thymeleaf.org"><head> <meta charset="UTF-8"> The < title > email < / title > < / head > < body > < div th: text = "${subject}" > < / div > < div > books list < table border = "1" > < tr > < td > book number < / td > The name of the book < td > < / td > < td > book 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>test.java@Autowiredprivate MailService mailService; @Autowiredprivate TemplateEngine templateEngine; @Testpublic void sendThymeleafMail() { Context context = new Context(); Context. setVariable("subject", "book inventory "); List<Book> books = Lists.newArrayList(); Books.add (new Book("Go Language Basics ", 1, "nonename", BigDecimal)); Books. add(new Book("Go Language Training ", 2, "Nonename ", BigDecimal.TEN)); Books.add (new Book("Go language Advanced ", 3, "nonename", BigDecimal. context.setVariable("books", books); String mail = templateEngine.process("mailtemplate.html", context); SendHtmlMail ("[email protected]", "[email protected]", "Book Catalog ", 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 > < the 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@EnableWebMvcpublic class SwaggerConfig { @Bean Docket docket() { 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", "= - = @ qq.com")) version (" v1.0 "). The title (" API test documents "). The license (" Apache2.0 ") LicenseUrl (" http://www.apache.org/licenese/LICENSE-2.0 "). The 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

Some interview questions for 2020 are summarized. The interview questions are divided into 19 modules, which are: Java Basics, Containers, Multithreading, Reflection, Object copy, JavaWeb exceptions, Networking, Design Patterns, Spring/SpringMVC, SpringBoot/SpringCloud, Hibernate, MyBatis, RabbitMQ, Kafka, Zookee Per, MySQL, Redis, JVM.

Get the following information: pay attention to the public number: [programmers with stories], get learning materials.

Remember to click follow + comment oh ~