敲开 SpringBoot 的大门

本文详细介绍了SpringBoot的作用,包括快速构建Spring应用、约定优于配置、避免XML配置等特性。接着,通过实例演示了从创建工程、添加依赖、编写启动类和Controller到Java配置的全过程,展示了SpringBoot如何简化配置和依赖管理。最后,探讨了Java配置的使用,包括属性注入和更优雅的注入方式。
摘要由CSDN通过智能技术生成

1、SpringBoot 的作用

谈及 SpringBoot,先要了解以下3个问题:
A、什么是 SpringBoot;
B、为什么要学习 SpringBoot;
C、SpringBoot 的特点;

1.1 什么是 SpringBoot

SpringBoot是Spring项目中的一个子工程,与我们所熟知的Spring-framework 同属于spring的产品:
spring 官网.
在这里插入图片描述
在 SpringBoot 下有这样一个介绍:
Takes an opinionated view of building production-ready Spring applications. Spring Boot favors convention over configuration and is designed to get you up and running as quickly as possible.
用一些固定的方式来构建生产级别的spring应用。Spring Boot 推崇约定大于配置的方式以便于你能够尽可能快速的启动并运行程序。

其实人们把Spring Boot 称为搭建程序的脚手架。其最主要作用就是帮我们快速的构建庞大的 spring 项目,并且尽可能的减少一切 xml 配置,做到开箱即用,迅速上手,让我们关注与业务而非配置。

1.2 为什么要学习 SpringBoot

java一直被人诟病的一点就是臃肿、麻烦。当我们还在辛苦的搭建项目时,可能Python程序员已经把功能写好了,究其原因注意是两点:
A、复杂的配置:项目各种配置其实是开发时的损耗, 因为在思考 Spring 特性配置和解决业务问题之间需要进行思维切换,所以写配置挤占了写应用程序逻辑的时间。
B、一个是混乱的依赖管理:项目的依赖管理也是件吃力不讨好的事情。决定项目里要用哪些库就已经够让人头痛的了,你还要知道这些库的哪个版本和其他库不会有冲突,这难题实在太棘手。并且,依赖管理也是一种损耗,添加依赖不是写应用程序代码。一旦选错了依赖的版本,随之而来的不兼容问题毫无疑问会是生产力杀手。

而 SpringBoot 让这一切成为过去!
Spring Boot 简化了基于Spring的应用开发,只需要 “run” 就能创建一个独立的、生产级别的 Spring 应用。Spring Boot 为Spring平台及第三方库提供开箱即用的设置(提供默认设置,存放默认配置的包就是启动器),这样我们就可以简单的开始。多数 Spring Boot 应用只需要很少的 Spring 配置。

我们可以使用 SpringBoot 创建 java 应用,并使用 java –jar 启动它,就能得到一个生产级别的web工程。

1.3 SpringBoot 的特点

Spring Boot 主要目标是:
A、为所有 Spring 的开发者提供一个非常快速的、广泛接受的入门体验;
B、开箱即用(启动器starter-其实就是SpringBoot提供的一个jar包),但通过自己设置参数(.properties),即可快速摆脱这种方式;
C、提供了一些大型项目中常见的非功能性特性,如内嵌服务器、安全、指标,健康检测、外部化配置等;
D、绝对没有代码生成,也无需 XML 配置。
更多细节,大家可以到spring 官网查看。

2、入门操作

接下来,我们就来利用SpringBoot搭建一个web工程,体会一下SpringBoot的魅力所在!

2.1 创建工程

我们先新建一个空的工程:
在这里插入图片描述
工程名为 springboot-demo:
在这里插入图片描述
在弹出的新界面上新建一个 Modules:
在这里插入图片描述
使用 maven 来构建:
在这里插入图片描述
构建项目组ID和项目名称:
在这里插入图片描述
项目存储路径:
在这里插入图片描述
点击 Finish 后,点击 Apply --> OK —> 项目创建成功:
在这里插入图片描述

2.2 添加依赖

看到这里很多同学会有疑惑,前面说传统开发的问题之一就是依赖管理混乱,怎么这里我们还需要管理依赖呢?难道SpringBoot 不帮我们管理吗?
​别着急,现在我们的项目与SpringBoot还没有什么关联。SpringBoot提供了一个名为spring-boot-starter-parent的工程,里面已经对各种常用依赖(并非全部)的版本进行了管理,我们的项目需要以这个项目为父工程,这样我们就不用操心依赖的版本问题了,需要什么依赖,直接引入坐标即可!

2.2.1 添加父工程坐标

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.1.8.RELEASE</version>
</parent>

2.2.2 添加web启动器

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

需要注意的是,我们并没有在这里指定版本信息。因为 SpringBoot 的父工程已经对版本进行了管理了。
这个时候,我们会发现项目中多出了大量的依赖:
在这里插入图片描述
这些都是 SpringBoot 根据 spring-boot-starter-web 这个依赖自动引入的,而且所有的版本都已经管理好,不会出现冲突。

2.2.3 管理 jdk 版本

默认情况下,maven工程的jdk版本是1.5,而我们开发使用的是1.8,因此这里我们需要修改jdk版本,只需要简单的添加以下属性即可:

<properties>
	<java.version>1.8</java.version>
</properties>

2.2.4 完整 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zc.sb</groupId>
    <artifactId>springboot-test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.8.RELEASE</version>
    </parent>

    <properties>
        <java.version>1.8</java.version>
    </properties>

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

2.3 启动类

SpringBoot 项目通过 main 函数即可启动,我们需要创建一个启动类:
在这里插入图片描述

然后编写 main 函数:

package com.zc;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @作者: zc
 * @时间: 2021/1/28 9:25
 * @描述: SpringBoot 程序启动类
 */

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

2.4 编写 controller

接下来,我们就可以像以前那样开发SpringMVC的项目了!
我们编写一个controller:(注意:controller类要放在主程序类的下级目录,此文档就是要在包com.zc下一级),
所以先建一个包 com.zc.controller:
在这里插入图片描述
controller 代码:

package com.zc.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @作者: zc
 * @时间: 2021/1/28 9:33
 * @描述: SpringBoot 入门测试
 */

@RestController //相当于 @Controller @ResponseBody
@RequestMapping(value = "test", produces = "text/html;charset=utf-8;")
public class HelloController {

    @RequestMapping("hello")
    public String hello(){
        return "Hello, SpringBoot...";
    }
}

2.5 启动测试

接下来,我们运行 main 函数,查看控制台:
在这里插入图片描述
可以看到启动端口在本地的 8080 端口,
A、本地监听的端口是8080
B、SpringMVC的映射路径是:/
C、/test/hello路径已经映射到了HelloController中的hello()方法,@RequestMapping value 值连接:
去浏览器输入地址:http://localhost:8080/test/hello
在这里插入图片描述
到此我们的 SpringBoot 测试成功了!

3、Java 配置

在入门案例中,我们没有任何的配置,就可以实现一个SpringMVC的项目了,快速、高效!
但是有同学会有疑问,如果没有任何的 xml,那么我们如果要配置一个 Bean 该怎么办?比如我们要配置一个数据库连接池,以前会这么玩:

<!-- 配置连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
      init-method="init" destroy-method="close">
    <property name="driver" value="${jdbc.driver}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
</bean>

现在该怎么做呢?

3.1 spring 历史

事实上,在 Spring3.0 开始,Spring 官方就已经开始推荐使用 java 配置来代替传统的 xml 配置了,我们不妨来回顾一下Spring 的历史:
(1)Spring1.0 时代:
在此时因为 jdk1.5 刚刚出来,注解开发并未盛行,因此一切 Spring 配置都是 xml 格式,想象一下所有的 bean 都用 xml 配置,细思极恐啊,心疼那个时候的程序员2秒
(2)Spring2.0 时代:
Spring 引入了注解开发,但是因为并不完善,因此并未完全替代 xml,此时的程序员往往是把 xml 与注解进行结合,貌似我们之前都是这种方式。
(3)Spring3.0 及以后:
Spring3.0 以后的注解已经非常完善了,因此 Spring 推荐大家使用完全的 java 配置来代替以前的 xml,不过似乎在国内并未推广盛行。然后当 SpringBoot 来临,人们才慢慢认识到 java 配置的优雅。

有句古话说的好:拥抱变化,拥抱未来。所以我们也应该顺应时代潮流,做时尚的弄潮儿,一起来学习下 java 配置的玩法。
目前国内的 spring 开发,是注解和 xml 配置相结合,注解一般被用来做 bean 的注入使用,xml 一般被用来做事务的声明等等。

3.2 尝试 java 配置

(1)java 配置主要靠 java 类和一些注解,比较常用的注解有:
A、@Configuration:声明一个类作为配置类,代替 xml 文件;
B、@Bean:声明在方法上,将方法的返回值加入 Bean 容器,方法名是 Bean 的名称,代替 标签;
C、@value:属性注入;
D、@PropertySource:指定外部属性文件。

@Bean
public DataSource dataSource(){
    ...
}
类似于
<bean id="dataSource" class="...DataSource"/>

(2)我们接下来用 java 配置来尝试实现连接池配置:
首先引入 Druid 连接池依赖:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.6</version>
</dependency>

(3)在资源文件 resources 下创建一个 jdbc.properties 文件,编写 jdbc 属性:

jdbc.driverName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db_sboot?characterEncoding=UTF-8&useSSL=false
jdbc.username=root
jdbc.password=root

(4)新建一个包 com.zc.config,编写代码 JdbcConfig.java:

package com.zc.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import javax.sql.DataSource;

/**
 * @作者: zc
 * @时间: 2021/1/28 10:18
 * @描述: JDBC 数据库连接配置类
 *        classpath:jdbc.properties 路径正确的话:
 *          按住键盘 Ctrl 键,点击鼠标左键便可跳转(@Value 参数也可跳转)
 *         
 * - `@Configuration`:声明我们 JdbcConfig 是一个配置类
 * - `@PropertySource`:指定属性文件的路径是:`classpath:jdbc.properties`
 * - 通过 `@Value` 为属性注入值
 * - 通过 @Bean 将 `dataSource()`方法声明为一个注册 Bean 的方法,Spring 会自动调用该方法,将方法的返回值加入 Spring 容器中。
 *       然后我们就可以在任意位置通过 `@Autowired` 注入 DataSource 了!
 */

@Configuration
@PropertySource("classpath:jdbc.properties")
public class JdbcConfig {
    @Value("${jdbc.driverName}")
    String driverName;
    @Value("${jdbc.url}")
    String url;
    @Value("${jdbc.username}")
    String username;
    @Value("${jdbc.password}")
    String password;

    @Bean
    public DataSource dataSource(){
        DruidDataSource dataSource= new DruidDataSource();
        dataSource.setDriverClassName(driverName);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }
}

(5)我们在 com.zc.controller.HelloController 中测试:

package com.zc.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.sql.DataSource;

/**
 * @作者: zc
 * @时间: 2021/1/28 9:33
 * @描述: SpringBoot 入门测试
 */

@RestController //相当于 @Controller @ResponseBody
@RequestMapping(value = "test", produces = "text/html;charset=utf-8;")
public class HelloController {

    @Autowired
    private DataSource dataSource;

    @RequestMapping("hello")
    public String hello(){
        return "Hello, SpringBoot..." + dataSource;
    }
}

(6)然后 Debug 运行并查看:
标记测试运行到 hello() return:
在这里插入图片描述
浏览器打开测试:http://localhost:8080/test/hello
因为程序在 debug,暂停在某处,所以页面会处于一直刷新等待状态:
在这里插入图片描述

查看 IDEA 控制台:
在这里插入图片描述
此时属性注入成功了!

3.3 SpringBoot 属性注入

在上面的案例中,我们实验了 java 配置方式。不过属性注入使用的是 @Value 注解。这种方式虽然可行,但是不够强大,因为它只能注入基本类型值。
在 SpringBoot 中,提供了一种新的属性注入方式,支持各种 java 基本数据类型及复杂类型的注入。
属性的 getter,setter等方法可加入 lombok 依赖:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.16</version>
</dependency>

(1)我们 com.zc.config 包下新建一个类 JdbcProperties.java,用来进行属性注入:

package com.zc.config;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * @作者: zc
 * @时间: 2021/1/28 10:50
 * @描述: jdbc 配置信息
 *
 * - 在类上通过 @ConfigurationProperties 注解声明当前类为属性读取类
 * - `prefix="jdbc"`读取属性文件中,前缀为jdbc的值。
 * - 在类上定义各个属性,名称必须与属性文件中`jdbc.`后面部分一致
 * - 需要注意的是,这里我们并没有指定属性文件的地址,
 *      所以我们需要把 jdbc.properties 名称改为 application.properties,
 *      这是 SpringBoot 默认读取的属性文件名:
 */

@ConfigurationProperties(prefix = "jdbc")
@Data // 所有 getter,setter 方法
@AllArgsConstructor // 所有参数构造函数
@NoArgsConstructor // 无参构造函数
public class JdbcProperties {
    private String url;
    private String driverName;
    private String username;
    private String password;
}

(2)修改 JdbcConfig.java 中使用这个属性(使用的是以下介绍的第三种写法):

package com.zc.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

/**
 * @作者: zc
 * @时间: 2021/1/28 10:18
 * @描述: JDBC 数据库连接配置类
 * 
 */

@Configuration
@EnableConfigurationProperties(JdbcProperties.class)
public class JdbcConfig {

    @Bean
    public DataSource dataSource(JdbcProperties jdbc) {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(jdbc.getUrl());
        dataSource.setDriverClassName(jdbc.getDriverName());
        dataSource.setUsername(jdbc.getUsername());
        dataSource.setPassword(jdbc.getPassword());
        return dataSource;
    }
}

通过 @EnableConfigurationProperties(JdbcProperties.class) 来声明要使用 JdbcProperties 这个类的对象
然后你可以通过以下方式注入 JdbcProperties 这个类的对象:
A、@Autowired 注入

@Autowired
private JdbcProperties prop;

B、构造函数注入:

private JdbcProperties prop;
public JdbcConfig(Jdbcproperties prop){
    this.prop = prop;
}

C、声明有 @Bean 的方法参数注入:

@Bean
public Datasource dataSource(JdbcProperties prop){
    // ...
}

(3)修改 HelloController 类:

package com.zc.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.sql.DataSource;

/**
 * @作者: zc
 * @时间: 2021/1/28 9:33
 * @描述: SpringBoot 入门测试
 */

// @Controller 和 @ResponseBody 相当于 @RestController
@Controller
@ResponseBody
public class HelloController {
    @Autowired
    private DataSource dataSource;

    @RequestMapping("data")
    public String hello(){
        return "hi:"+dataSource;  //在此处设置断点,启动localhost:8080/data看控制台结果
    }

}

(4)测试:
在这里插入图片描述
测试结果:
在这里插入图片描述
大家会觉得这种方式似乎更麻烦了,事实上这种方式有更强大的功能,也是SpringBoot推荐的注入方式。两者对比关系:
在这里插入图片描述
优势:

  • Relaxed binding:松散绑定
    • 不严格要求属性文件中的属性名与成员变量名一致。支持驼峰,中划线,下划线等等转换,甚至支持对象引导。比如:user.friend.name:代表的是user对象中的friend属性中的name属性,显然friend也是对象。@value注解就难以完成这样的注入方式。
  • meta-data support:元数据支持,帮助IDE生成属性提示(写开源框架会用到)。

3.4 更优雅的注入

事实上,如果一段属性只有一个Bean需要使用,我们无需将其注入到一个类(JdbcProperties)中。而是直接在需要的地方声明即可:
修改 JdbcConfig 类:

package com.zc.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

@Configuration
public class JdbcConfig {

    @Bean
    // 声明要注入的属性前缀,SpringBoot 会自动把相关属性通过 set 方法注入到 DataSource 中
    @ConfigurationProperties(prefix = "jdbc")
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        return dataSource;
    }
}

JdbcProperties 类中 @ConfigurationProperties(prefix = “jdbc”) 注释掉;

我们直接把 @ConfigurationProperties(prefix = “jdbc”) 声明在需要使用的 @Bean 的方法上,然后 SpringBoot 就会自动调用这个 Bean(此处是DataSource)的 set 方法,然后完成注入。使用的前提是:该类必须有对应属性的 set 方法!

再次测试:
在这里插入图片描述
发现 driverClass 为空:
原因:我们的配置文件 application.properties 中 driver 名称是 jdbc.driverName,修改为:jdbc.driverClassName
再将 JdbcProperties 类中的私有属性 driverName 改与配置文件相同 driverClassName;

再次测试:
在这里插入图片描述
属性正常注入。

3.5 更简单的方式,通过配置文件 application.yml

此处不研究了…

jdbc:
  driverClassName: com.mysql.jdbc.Driver
  url: jdbc:mysql://localhost:3306/db_ssm?characterEncoding=UTF-8&useSSL=false
  username: root
  password: root
  ///
  user:
    name: lisi
    age: 22
    language: [java,php,python]
      - java
      - php
      - python
    map: {k1: v1,k2: v2}
好的,下面是一个简单的Spring Boot登录验证代码示例: 首先,需要在pom.xml中添加Spring Boot Web和Spring Boot Security的依赖: ```xml <dependencies> <!-- Spring Boot Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Spring Boot Security --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> </dependencies> ``` 然后,创建一个SecurityConfig类来配置Spring Security: ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService); } @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/", "/login").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .defaultSuccessUrl("/home") .permitAll() .and() .logout() .logoutUrl("/logout") .permitAll(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } } ``` 上面的代码配置了Spring Security的登录页面、注销、用户认证和权限控制等相关信息。 然后,创建一个UserDetailsServiceImpl类来实现UserDetailsService接口,用于获取用户的详细信息: ```java @Service public class UserDetailsServiceImpl implements UserDetailsService { @Autowired private UserRepository userRepository; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User user = userRepository.findByUsername(username); if (user == null) { throw new UsernameNotFoundException("用户不存在"); } List<GrantedAuthority> authorities = new ArrayList<>(); authorities.add(new SimpleGrantedAuthority("ROLE_USER")); return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), authorities); } } ``` 最后,创建一个UserController类来处理登录相关的请求: ```java @RestController public class UserController { @GetMapping("/") public String index() { return "欢迎访问首页!"; } @GetMapping("/login") public String login() { return "请登录!"; } @GetMapping("/home") public String home() { return "欢迎回来!"; } } ``` 上面的代码处理了首页、登录和主页的请求。 以上就是一个简单的Spring Boot登录验证代码示例,希望能对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值