SpringBoot从入门到精通(全)

635 阅读20分钟

前言

本博文结合软件idea进行主要讲解

文中主要的学习视频主要通过
最新SpringBoot2教程-从零深入SpringBoot【实战解读SpringBoot】

博文中的源码主要在
源码课程

更多Java知识点:java框架零基础从入门到精通的学习路线(超全)

springboot的特性主要有

  • 简化 Spring 应用程序的创建和开发过程
  • 抛弃了繁琐的 xml 配置过程,采用大量的默认配置简化以及注解反射
  • 直接使用 java main 方法启动内嵌的 Tomcat 服务器运行 Spring Boot 程序,不需要部署 war 包文件

四大核心分别为自动配置、起步依赖、Actuator和命令行界面

1. 入门案例

1.1 新建项目

创建一个基本的springboot项目
springboot的初始化结构默认是需要连接网络的
在这里插入图片描述

以下大部分是默认设置,主要填写项目名包名等
修改java的version为8
在这里插入图片描述
下一步为设置依赖信息
springboot是web工程,选择web工程,版本是最新版本,不要选择SNAPSHOT测试版本。RELEASE为最新稳定版本。
在这里插入图片描述
最后的工程目录为
.gitignore为设置可忽视的后缀名文件
mcnw名字系列为命令行界面
我们只需要关注pom.xml文件即可
在这里插入图片描述
springboot也是基于maven项目
有parent父工程以及子工程,其版本信息可不一致
查看pom.xml文件

  • springboot框架下web项目的起步依赖信息、测试起步依赖信息以及打包编译的插件
    具体起步依赖信息和测试起步依赖信息的版本号多数跟父工程
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

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

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

123456789101112131415161718192021

查看其它目录结构文件
在这里插入图片描述

  • 在static中主要存放的是css、html等静态文件
  • templates为前端模板
  • application.properties为核心配置文件

springboot的启动入口类在main下,test文件同理

  • 核心注解,主要用于开启spring自动配置
@SpringBootApplication
public class DemoApplication {

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

}

12345678

1.2 代码模板

以下代码可能会出现maven项目的配置问题或者springboot的出错可查看我之前的文章
1.maven:编译出现Process terminated解决方法

2.springboot:出现Could not transfer artifact org.springframework.boot:spring-boot-等问题解决方法

springboot项目代码必须放到Application类所在的同级目录或下级目录

//SpringBoot项目启动入口类
@SpringBootApplication  //开启springboot配置
public class Application {

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

}

123456789

在下一级目录中新建一个类
添加注解
value设置的是路径。通过tomcat访问,后面加此路径即可

@Controller
public class IndexController {

    @RequestMapping(value = "/springboot/say")
    public @ResponseBody String say() {
        return "Hello,SpringBoot!";
    }
}

12345678

运行主函数之后出现如图所示即可
在这里插入图片描述
在网页中输入http://localhost:8080/springboot/say
即可访问网址
在这里插入图片描述
可以以map的方式出现

@RequestMapping(value = "/mapvalue")
public @ResponseBody Map<String,Object> mapvalue() {
     Map<String,Object> retMap = new HashMap<String, Object>();
     retMap.put("message","SpringBoot Project");

  return retMap;
}

1234567

访问网址的格式如下
http://localhost:8081/springboot/mapvalue
在这里插入图片描述
可以以传参格式进入

@Controller
public class IndexController {


    @RequestMapping(value = "/say")
    public @ResponseBody Object say(String message) {

        return "Say:Hello " + message;
    }
}

12345678910

具体传参的格式截图如下
http://localhost:9090/yaml/say?message=3
在这里插入图片描述

总结以上模板主要有@Controller、@RequestMapping以及@ResponseBody注解等

2. 配置详解

2.1 核心配置文件properties

如果不做设置的时候会自动配置,如果不想自动可以自已设置内嵌Tomcat端口号以及上下文根,上下文根必须加/

  • 一个工程文件只能有一个核心配置文件
#设置内嵌Tomcat端口号
server.port=8081

#设置上下文根
server.servlet.context-path=/springboot

12345

在网页中输入http://localhost:8081/springboot/say

配置完成之后的显示为
在这里插入图片描述

2.2 核心配置文件yml、yaml

yml、yaml配置文件比较少用
注释该配置文件后面加--
删除properties配置文件建立一个yml后缀的文件

在这里插入图片描述
具体配置信息如下
yml配置文件主要采用前后的空格以及tab键位格式
值前面需要有空格

server:
  port: 8081
  servlet:
    context-path: /

1234

同理yaml配置文件也一样

server:
  port: 9090
  servlet:
    context-path: /yaml

1234

在网页中输入http://localhost:9090/yaml/say

如果配置文件properties和yml都存在,则以properties配置文件为主
涉及其他配置文件比如maven的私服
可查看我之前的文章Maven详细配置(全)
剖析配置主要是这一段导致而已

<mirrors>

<mirror>

<id>alimaven</id>

<name>aliyun maven</name>

<!-- https://maven.aliyun.com/repository/public/ -->


<url>http://maven.aliyun.com/nexus/content/groups/public/</url>

<mirrorOf>central</mirrorOf>

</mirror>

</mirrors>

<!-- 配置: java8, 先从阿里云下载, 没有再去私服下载 -->

1234567891011121314151617181920

2.3 多环境核心配置文件properties

工作中的开发环境:开发、测试、准生产和生产四种环境
ip地址用户环境等可能都不一样
所以需要配置四个环境
在这里插入图片描述
比如开发环境的配置文件

#开发环境配置文件
server.port=8080
server.servlet.context-path=/dev

123

但环境太多,需要配置一个主配置环境当前使用的是哪一个
则在application.properties中书写
active的激活配置文件主要是根据application-xxx后面的xxx必须是英文不能是中文

#springboot主核心配置文件
#激活使用的配置文件
spring.profiles.active=dev

123

2.4 多环境核心配置文件yml

yml同理properties配置文件
在这里插入图片描述
配置一个yml配置文件

server:
  port: 8080
  servlet:
    context-path: /product

1234

配置一个主yml配置文件

spring:
  profiles:
    active: product

123

2.5 自定义配置

2.5.1 @value

主要是为了取值
这个是设置了配置文件,在类中使用 @value来取值

在properties核心配置文件中
添加自定义的配置

#设置内嵌tomcat端口号
server.port=8080
#设置上下文根
server.servlet.context-path=/


school.name=manongyanjiuseng
websit=http://www.manongyanjiuseng.com

12345678

通过配置一个一个@Value
在代码中通过用注解的方式去取用@Value
通过@Value(${ })传值进入
赋值给一个参数比如private String schoolName;

@Value("${school.name}")
private String schoolName;

@Value("${websit}")
private String websit;

@RequestMapping(value = "/say")
public @ResponseBody String say() {
    return "Hello:" + schoolName + ":" + websit;
}

12345678910

2.5.2 @ConfigurationProperties

与上面的区别就是没有直接用@value
而是通过一个注解类
最后引用的是对象而不是所属值

通过对象注解,引用核心配置文件

@ConfigurationProperties主要是为了映射对象
@Component将此类将给spring容器进行管理

自定义配置为

server.port=8080
server.servlet.context-path=/

school.name=manongyanjiuseng
websit=http://码农研究僧个人博客

abc.name=abc
abc.websit=http://码农研究僧个人博客



12345678910

在代码中这样书写@ConfigurationProperties此为核心配置类
@ConfigurationProperties必须有前缀prefix
如果有同名属性可以用这个

@Component//将此类将给spring容器进行管理
@ConfigurationProperties(prefix = "school")
public class School {

    private String name;

    private String websit;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getWebsit() {
        return websit;
    }

    public void setWebsit(String websit) {
        this.websit = websit;
    }
}

123456789101112131415161718192021222324

在主函数中通过注解的方式进行@Autowired

@Controller
public class IndexController {

    @Autowired
    private School school;

    @Autowired
    private Abc abc;

    @RequestMapping(value = "/say")
    public @ResponseBody String say() {


        return "school.name="+school.getName()+"-----school.websit="+school.getWebsit() + "====abc.name"+abc.getName()+"===abc.websit="+abc.getWebsit();
    }
}

12345678910111213141516

特别注意
使用@ConfigurationProperties 注解出现警告问题
可以在pom.xml配置文件中加入以下配置

<!--解决使用@ConfigurationProperties 注解出现警告问题-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

123456

截图如下
在这里插入图片描述

3. springboot之web工程

3.1 集成jsp

存放jsp文件目录结构为
在这里插入图片描述
在main下新建一个webapp并将该目录设置为web资源文件

具体配置可查看我之前的文章
Tomcat:HTTP状态 404 - 未找到解决方法
在这里插入图片描述

  • Springboot项目默认推荐使用的前端引擎是thymeleaf,要使用springboot集成jsp,需要添加依赖信息,以及手动指定jsp最后编译的路径而且springboot集成jsp,编译jsp的路径是springboot规定好的位置META-INF/resources

jsp的依赖信息放在xml配置中

<!--引入SpringBoot内嵌Tomcat对jsp的解析依赖,不添加解析不了jsp-->
<!--仅仅只是展示jsp页面,只添加一个依赖-->
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
</dependency>

123456

指定jsp路径需要放在pom.xml配置文件中的build中

<resources>
    <resource>
        <!--源文夹-->
        <directory>src/main/webapp</directory>
        <!--指定编译到META-INF/resources-->
        <targetPath>META-INF/resources</targetPath>
        <!--指定源文件夹中的哪个资源要编译进行-->
        <includes>
            <include>*.*</include>
        </includes>
    </resource>
</resources>

123456789101112

还需要配置视图解析器
配置在application.properties中

#配置视图解析器
spring.mvc.view.prefix=/
spring.mvc.view.suffix=.jsp

123

java文件格式调用为
集成jsp页面不用@ResponseBody这个注解
集成jsp有两种比较,注意对比以及区别
后面会经常使用到
传入的第一个参数是给前端使用的

@Controller
public class IndexController {

    @RequestMapping(value = "/say")
    public ModelAndView say() {
        ModelAndView mv = new ModelAndView();
        mv.addObject("message","Hello,SpringBoot");
        mv.setViewName("say");
        return mv;
    }

	//也可以
    @RequestMapping(value = "/index")
    public String index(Model model) {
        model.addAttribute("message","HelloWorld");
        return "say";
    }
}

123456789101112131415161718

注意上面这两者的区别

  • 一个是传入model的这个对象,之后通过addAttribute这个方法将其添入,第一个参数是jsp传参的参数
  • 另一个是直接定义ModelAndView这个方法,使用这个类的addObject将其jsp中参数传入

代码中具体的参数可看我这篇文章
SpringMVC之ModelAndView类详细分析(全)

jsp具体内容为

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>${message}</h1>
</body>
</html>

123456789

最后具体的截图如下
在这里插入图片描述
总的来说这个有两种模板
模板如下

@RequestMapping(value = "/index")
public String index(Model model) {
    model.addAttribute("data","SpringBoot Thymeleaf");
    return "index";
}

@RequestMapping(value = "/index1")
public ModelAndView index1() {
    ModelAndView mv = new ModelAndView();
    mv.setViewName("index");
    mv.addObject("data","SpringBoot");
    return mv;
}

//放入对象
@RequestMapping(value = "/user/detail")
public ModelAndView userDetail() {
    ModelAndView mv = new ModelAndView();
    User user = new User();
    user.setId(1001);
    user.setAge(23);
    user.setUsername("lisi");

    mv.setViewName("userDetail");
    mv.addObject("user",user);

    return mv;
}

12345678910111213141516171819202122232425262728

3.2 集成Mybatis

需要添加mybatis的依赖以及mysql驱动

<!--MySQL驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <!--<version>5.1.9</version>-->
</dependency>

<!--MyBatis整合SpringBoot框架的起步依赖-->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.0.0</version>
</dependency>

12345678910111213

通过使用mybatis逆向工程集成
可看我之前的文章
mybatis逆向工程详细配置讲解(全)

通过逆向工程生成的映射,具体如何使用
可继续往下看

接口类

public interface StudentService {

    /**
     * 根据学生ID查询详情
     * @param id
     * @return
     */
    Student queryStudentById(Integer id);
}

123456789

接口实现类
通过@Service注解进行说明,通过 @Autowired进行对象注入,之后可以使用他的函数

@Service
public class StudentServiceImpl implements StudentService {

    @Autowired
    private StudentMapper studentMapper;

    @Override
    public Student queryStudentById(Integer id) {
        return studentMapper.selectByPrimaryKey(id);
    }
}


123456789101112

具体如何使用他的函数主要是通过mapper的映射类进行标注
通过@Mapper 扫描DAO接口到spring容器
在这里插入图片描述

在用户层界面上实现他的逻辑代码
主要代码如下
通过@Controller进行注解说明,通过 @Autowired进行对象注入

@Controller
public class StudentController {

    @Autowired
    private StudentService studentService;

    @RequestMapping(value = "/student")
    public @ResponseBody Object student(Integer id) {

        Student student = studentService.queryStudentById(id);

        return student;
    }
}

1234567891011121314

最后还要配置数据库的用户信息,才可进行使用

#设置连接数据库的配置
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.154.128:3306/springboot?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123

12345

补充说明
由于mapper文件中的映射文件在src上,而且是xml文件结尾
编译的时候执行的结果不会出来
所以要添加扫描
再pom.xml文件中添加如下

<resources>
    <resource>
        <directory>src/main/java</directory>
        <includes>
            <include>**/*.xml</include>
        </includes>
    </resource>
</resources>

12345678

第二种方案是:
将其mapper的映射文件移到resources上
之后再连接数据库配置末尾添加如下

#指定MyByBatis映射文件的路径
mybatis.mapper-locations=classpath:mapper/*.xml

12

基于以上两种方式
在最后都要在springboot中添加如下注解,之后pom.xml文件可以将其删除

@SpringBootApplication  //开启spring配置
@MapperScan("com.bjpowernode.springboot.mapper") //开启扫描Mapper接口的包以及子目录
public class Application {

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

}

123456789

3.3 事务

事务是一个完整的功能,也叫做一个完整的事务
事务只跟数据库的DML语句有关系:增删改

具体例子如下
通过逆向工程生成mapper和类等
之后添加相对应的控制层界面@Controller
在界面中定义接口类,以及要实现的接口实现类函数
接口实现类传入的参数是mapper映射的类

@Controller
public class StudentController {

    @Autowired
    private StudentService studentService;

    @RequestMapping(value = "/update")
    public @ResponseBody Object update(Integer id,String name) {
        Student student = new Student();
        student.setId(id);
        student.setName(name);
        int updateCount = studentService.updateStudentById(student);

        return "修改学生编号为"+id+"的姓名修改结果:"+updateCount;
    }
}

12345678910111213141516

接口类为

public interface StudentService {

    /**
     * 根据学生ID修改学生信息
     * @param student
     * @return
     */
    int updateStudentById(Student student);
}

123456789

接口实现类为
为了更好的实现事务的回滚,此处添加了一个bug
正常情况下应该不允许修改

@Service
public class StudentServiceImpl implements StudentService {

    @Autowired
    private StudentMapper studentMapper;

    
    @Override
    public int updateStudentById(Student student) {

        //修改成功
        int i = studentMapper.updateByPrimaryKeySelective(student);

        //失败
        int a = 10/0;

        return i;
    }
}

12345678910111213141516171819

因为在xml中有配置文件,且在src目录下的
所以需要配置@MapperScan(basePackages = "com.bjpowernode.springboot.mapper")

@SpringBootApplication
@MapperScan(basePackages = "com.bjpowernode.springboot.mapper")
@EnableTransactionManagement    //开启事务(可选项)
public class Application {

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

}

12345678910

最后在资源环境下还要添加sql的数据库信息
在这里插入图片描述
基于以上代码,最后还是修改成功
是因为还没有添加事务的回滚
具体添加回滚可以在接口实现类的函数中添加 @Transactional
并且在加载类中添加@EnableTransactionManagement //开启事务(可选项)

3.4 SpringmMVC常用注解

@Controller 处理 http 请求

如果控制层类上有实现的方法函数
@RestController //相当于控制层类上加@Controller + 方法上 @ResponseBody意味着当前控制层类中所有方法返还的都是JSON对象

在这里插入图片描述
@RequestMapping支持 Get 请求,也支持 Post 请求,本身第二个参数就是选择这个
@GetMapping 该注解通过在查询数据的时候使用 -> 查询
@PostMapping 该注解通常在新增数据的时候使用 -> 新增
@DeleteMapping 该注解通常在删除数据的时候使用 -> 删除
@PutMapping 该注解通常在修改数据的时候使用 -> 更新

具体代码展示逻辑

//@Controller
@RestController  //相当于控制层类上加@Controller + 方法上加@ResponseBody
// 意味着当前控制层类中所有方法返还的都是JSON对象
public class StudentController {


    @RequestMapping(value = "/student")
//    @ResponseBody
    public Object student() {
        Student student = new Student();
        student.setId(1001);
        student.setName("zhangsan");
        return student;
    }

    //该方法请求方式支持:GET和POST请求
    @RequestMapping(value = "/queryStudentById",method = {RequestMethod.GET,RequestMethod.POST})
    public Object queryStudentById(Integer id) {
        Student student = new Student();
        student.setId(id);
        return student;
    }


//    @RequestMapping(value = "/queryStudentById2",method = RequestMethod.GET)
    @GetMapping(value = "/queryStudentById2") //相当于上一句话,只接收GET请求,如果请求方式不对会报405错误
    //该注解通过在查询数据的时候使用 -> 查询
    public Object queryStudentById2() {
        return "Ony GET Method";
    }

//    @RequestMapping(value = "/insert",method = RequestMethod.POST)
    @PostMapping(value = "/insert") //相当于一句话
    //该注解通常在新增数据的时候使用 -> 新增
    public Object insert() {
        return "Insert success";
    }

//    @RequestMapping(value = "/delete",method = RequestMethod.DELETE)
    @DeleteMapping(value = "/delete")//相当于上一句话
    //该注解通常在删除数据的时候使用 -> 删除
    public Object delete() {
        return "delete Student";
    }


//    @RequestMapping(value = "/update",method = RequestMethod.PUT)
    @PutMapping(value = "/update") //相当于上一句话
    //该注解通常在修改数据的时候使用 -> 更新
    public Object update() {
        return "update student info1";
    }
}


123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354

3.5 RESTful

通常在RESTful风格中方法的请求方式会按增删改查的请求方式来区分或者修改请求路径
RESUful请求风格要求路径中使用的单词都是名称,最好不要出现动词

主要的注解有:
@PathVariable 获取 url 中的数据

具体的实现代码如下

@RestController
public class StudentController {


    @RequestMapping(value = "/student")
    public Object student(Integer id,Integer age) {
        Student student = new Student();
        student.setId(id);
        student.setAge(age);
        return student;
    }

//    @RequestMapping(value = "/student/detail/{id}/{age}")
    @GetMapping(value = "/student/detail/{id}/{age}")
    public Object student1(@PathVariable("id") Integer id,
                           @PathVariable("age") Integer age) {
        Map<String,Object> retMap = new HashMap<>();

        retMap.put("id",id);
        retMap.put("age",age);
        return retMap;
    }

//    @RequestMapping(value = "/student/detail/{id}/{status}")
    @DeleteMapping(value = "/student/detail/{id}/{status}")
    public Object student2(@PathVariable("id") Integer id,
                           @PathVariable("status") Integer status) {
        Map<String,Object> retMap = new HashMap<>();

        retMap.put("id",id);
        retMap.put("status",status);
        return retMap;
    }

    //以上代码student1和student2会出现请求路径冲突问题
    //通常在RESTful风格中方法的请求方式会按增删改查的请求方式来区分
    //修改请求路径
    //RESUful请求风格要求路径中使用的单词都是名称,最好不要出现动词

    @DeleteMapping(value = "/student/{id}/detail/{city}")
    public Object student3(@PathVariable("id") Integer id,
                           @PathVariable("city") Integer city) {
        Map<String,Object> retMap = new HashMap<>();

        retMap.put("id",id);
        retMap.put("city",city);
        return retMap;
    }

    @PostMapping(value = "/student/{id}")
    public String addStudent(@PathVariable("id") Integer id) {
        return "add student ID:" + id;
    }

    @PutMapping(value = "/student/{id}")
    public String updateStudent(@PathVariable("id") Integer id) {
        return "update Student ID:" +id;
    }
}

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859

3.6 集成redis

具体这部分的内容知识点可查看我之前的文章
Redis框架从入门到学精(全)
需要配置依赖文件

<!--SpringBoot集成Redis的起步依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

12345

还要设置redis服务器的具体信息

#设置redis配置信息
spring.redis.host=192.168.154.128
spring.redis.port=6379
spring.redis.password=123456

1234

接口代码

public interface StudentService {

    /**
     * 将值存放到redis中
     * @param key
     * @param value
     */
    void put(String key, String value);

    /**
     * 从redis中获取指定key的值
     * @param key
     * @return
     */
    String get(String key);
}

12345678910111213141516

接口实现代码

@Service
public class StudentServiceImpl implements StudentService {

    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    @Override
    public void put(String key, String value) {

        redisTemplate.opsForValue().set(key,value);

    }

    @Override
    public String get(String key) {

        String count = (String) redisTemplate.opsForValue().get(key);

        return count;
    }
}


12345678910111213141516171819202122

具体代码的实现类为

@Controller
public class StudentController {

    @Autowired
    private StudentService studentService;

    @RequestMapping(value = "/put")
    public @ResponseBody Object put(String key,String value) {

        studentService.put(key,value);

        return "值已成功放入redis";
    }

    @RequestMapping(value = "/get")
    public @ResponseBody String get() {
        String count = studentService.get("count");
        return "数据count为:" + count;
    }
}

1234567891011121314151617181920

以上用到一个模板主要是通过依赖文件引入
具体可查看这篇文章
RedisTemplate操作Redis,这一篇文章就够了(一)

3.7 集成dubbo

这部分内容的知识可看我之前的文章
Dubbo从入门到精通(全)

实现dubbo要有3个工程

  • 接口:存放实体bean和业务接口
  • 服务提供者:业务接口的实现类并且将服务暴露且注册到注册中心,调用数据持久层。主要的步骤是添加依赖(dubbo、注册中心、接口工程),配置服务提供者核心配置文件
  • 服务消费者:处理浏览器客户端发送的请求,从注册中心调用服务提供者所提供的服务。主要的步骤是添加依赖(dubbo、注册中心、接口工程),配置服务消费者核心配置文件

依赖文件都是相同的
主要如下

<!--Dubbo集成SpringBoot框架起步依赖-->
<dependency>
    <groupId>com.alibaba.spring.boot</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>2.0.0</version>
</dependency>

<!--注册中心-->
<dependency>
    <groupId>com.101tec</groupId>
    <artifactId>zkclient</artifactId>
    <version>0.10</version>
</dependency>

<!--接口工程-->
<dependency>
    <groupId>com.bjpowernode.springboot</groupId>
    <artifactId>020-springboot-dubbo-interface</artifactId>
    <version>1.0.0</version>

12345678910111213141516171819

服务消费者:
实现业务逻辑的一个层面
此处比往常多了一个表示dubbo接口暴露的注解@Reference(interfaceClass = StudentService.class,version = "1.0.0",check = false)

@Controller
public class StudentController {
    //dubbo:reference interface="" version="" check=false
    @Reference(interfaceClass = StudentService.class,version = "1.0.0",check = false)
    private StudentService studentService;

    @RequestMapping(value = "/student/count")
    public @ResponseBody Object studentCount() {

        Integer allStudentCount = studentService.queryAllStudentCount();

        return "学生总人数为:"+allStudentCount;
    }
}

1234567891011121314

服务提供者:

接口交给spring容器@Component
暴露接口需要使用这个 @Service(interfaceClass = StudentService.class,version = "1.0.0",timeout = 15000)

@Component
@Service(interfaceClass = StudentService.class,version = "1.0.0",timeout = 15000)
//dubbo:service interface="" version="" timeout=""
public class StudentServiceImpl implements StudentService {

    @Override
    public Integer queryAllStudentCount() {

        //调用数据持久层

        return 1250;
    }
}


1234567891011121314

接口工程:

public interface StudentService {

    /**
     * 获取学生总人数
     * @return
     */
    Integer queryAllStudentCount();
}

12345678

在消费者和服务提供者的配置类中
还要添加一个开启dubbo的配置,不一样注解不一样的开启配置

@SpringBootApplication      //开启spring配置
@EnableDubboConfiguration   //开启dubbo配置
public class Application {

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

}

123456789

3.8 集成ssm

主要集成了dubbo、mybatis、spring、springmvc和jsp
一共有三个工程量

  • 接口工程:存放实体bean和业务接口
  • 服务提供者:集成mybatis、redis
    添加依赖文件:mybatis依赖,mysql驱动依赖,dubbo依赖,zookeeper依赖,redis依赖,接口工程
    配置核心配置文件:配置连接数据库,配置连接redis,配置dubbo
  • 服务消费者:集成jsp,dubbo
    添加依赖文件:dubbo依赖,zookeeper依赖,解析jsp页面的依赖,接口工程
    配置核心配置文件:配置视图解析器,配置dubbo

主要的代码逻辑步骤如下
先导入逆向工程代码以及配置逆向工程的依赖文件
注意这个地方的model和mapper文件归属不一样的工程
在这里插入图片描述
以及依赖文件

<!--mybatis 代码自动生成插件-->
<plugin>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-maven-plugin</artifactId>
    <version>1.3.6</version>
    <configuration>
        <!--配置文件的位置-->
        <configurationFile>GeneratorMapper.xml</configurationFile>
        <verbose>true</verbose>
        <overwrite>true</overwrite>
    </configuration>
</plugin>

123456789101112

之后生成对应的文件结构

消费者的工程类
配置依赖文件

<!--SpringBoot框架web项目起步依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!--Dubbo集成SpringBoot框架起步依赖-->
<dependency>
    <groupId>com.alibaba.spring.boot</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>2.0.0</version>
</dependency>

<!--zookeeper注册中心-->
<dependency>
    <groupId>com.101tec</groupId>
    <artifactId>zkclient</artifactId>
    <version>0.10</version>
</dependency>

<!--接口工程-->
<dependency>
    <groupId>com.bjpowernode.springboot</groupId>
    <artifactId>023-springboot-dubbo-ssm-interface</artifactId>
    <version>1.0.0</version>
</dependency>

<!--SpringBoot集成JSP,仅仅只是展示JSP页面需要添加解析jsp页面的依赖-->
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
</dependency>

1234567891011121314151617181920212223242526272829303132

书写代码逻辑类
控制层面的代码
@Reference暴露端口
通过model去接收该类

@Controller
public class StudentController {

    @Reference(interfaceName = "com.bjpowernode.springboot.service.StudentService",version = "1.0.0",check = false)
    private StudentService studentService;

    @RequestMapping(value = "/student/detail/{id}")
    public String studentDetail(Model model,
                                @PathVariable("id") Integer id) {

        Student student = studentService.queryStudentById(id);

        model.addAttribute("student",student);

        return "studentDetail";
    }

    @GetMapping(value = "/student/all/count")
    public @ResponseBody Object allStudentCount() {

        Integer allStudentCount = studentService.queryAllStudentCount();

        return "学生总人数为:"+allStudentCount;
    }


}

123456789101112131415161718192021222324252627

配置文件
不用声明dubbo的消费者配置
因为还有jsp页面,所以还要配置jsp的视图解析器

#设置内嵌Tomcat端口号
server.port=8080
server.servlet.context-path=/

#设置dubbo配置
spring.application.name=025-springboot-dubbo-ssm-consumer
spring.dubbo.registry=zookeeper://192.168.154.128:2181

#配置视图解析器
spring.mvc.view.prefix=/
spring.mvc.view.suffix=.jsp


123456789101112

jsp还需要配置资源位置

<resource>
    <directory>src/main/webapp</directory>
    <targetPath>META-INF/resources</targetPath>
    <includes>
        <include>*.*</include>
    </includes>
</resource>

1234567

jsp的主要页面也就是传参进入而已

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>学生详情</title>
</head>
<body>
<h3>学生编号:${student.id}</h3>
<h3>学生姓名:${student.name}</h3>
<h3>学生年龄:${student.age}</h3>
</body>
</html>


123456789101112

提供者的代码
配置依赖文件

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

<!--Dubbo集成SpringBoot起步依赖-->
<dependency>
    <groupId>com.alibaba.spring.boot</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>2.0.0</version>
</dependency>

<!--注册中心-->
<dependency>
    <groupId>com.101tec</groupId>
    <artifactId>zkclient</artifactId>
    <version>0.10</version>
</dependency>

<!--MyBatis集成Springboot起步依赖-->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.0.0</version>
</dependency>

<!--MySQL驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

<!--SpringBoot集成Redis起步依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!--接口工程-->
<dependency>
    <groupId>com.bjpowernode.springboot</groupId>
    <artifactId>023-springboot-dubbo-ssm-interface</artifactId>
    <version>1.0.0</version>
</dependency>

1234567891011121314151617181920212223242526272829303132333435363738394041424344

还需要添加一个扫面xml文件的
因为逆向工程生成的mapper在src目录下

<resource>
    <directory>src/main/java</directory>
    <includes>
        <include>**/*.xml</include>
    </includes>
</resource>

123456

代码逻辑的实现类
通过spring的容器对象进行注解@Component
暴露端口@Service

@Component
@Service(interfaceName = "com.bjpowernode.springboot.service.StudentService",version = "1.0.0",timeout = 15000)
public class StudentServiceImpl implements StudentService {

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    @Override
    public Student queryStudentById(Integer id) {
        return studentMapper.selectByPrimaryKey(id);
    }

    @Override
    public Integer queryAllStudentCount() {

        //提升系统性能,用户体验提升
        //首先去redis缓存中查询,如果有:直接使用,如果没有:去数据库查询并存放到redis缓存中
        Integer allStudentCount = (Integer) redisTemplate.opsForValue().get("allStudentCount");

        //判断是否有值
        if (null == allStudentCount) {

            //去数据库查询
            allStudentCount = studentMapper.selectAllStudentCount();

            //并存放到redis缓存中
            redisTemplate.opsForValue().set("allStudentCount",allStudentCount,30, TimeUnit.SECONDS);
        }

        return allStudentCount;
    }
}


123456789101112131415161718192021222324252627282930313233343536

配置文件

#配置内嵌Tomcat端口号
server.port=8081
#设置上下文根
server.servlet.context-path=/

#设置连接数据库信息
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.154.128:3306/springboot?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123

#设置dubbo配置
spring.application.name=024-springboot-dubbo-ssm-provider
#声明当前工程为服务提供者
spring.dubbo.server=true
#设置注册中心
spring.dubbo.registry=zookeeper://192.168.154.128:2181

#设置redis配置
spring.redis.host=192.168.154.128
spring.redis.port=6379
spring.redis.password=123456

12345678910111213141516171819202122

在启动配置类中要添加以下注解
还要有包的扫描类,主要是配置mapper的

@SpringBootApplication
@MapperScan(basePackages = "com.bjpowernode.springboot.mapper")
@EnableDubboConfiguration   //开启dubbo配置
public class Application {

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

}

12345678910

接口类
这个接口类有逆向工程生成的java类
还要书写上面的接口类

public interface StudentService {

    /**
     * 根据学生ID查询详情
     * @param id
     * @return
     */
    Student queryStudentById(Integer id);

    /**
     * 获取学生总人数
     * @return
     */
    Integer queryAllStudentCount();

}

12345678910111213141516

4. springboot之非web工程

没有webapp这个工程目录了
在选定的时候
不要勾选这个选项就是非web工程,勾选了就是web工程
在这里插入图片描述

创建依赖文件

<dependencies>
    <!--SpringBoot框架非web应用起步依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <!--SpringBoot框架测试起步依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

1234567891011121314151617181920

对比一下web工程的依赖文件就会显示出有很大的不同

接口类

public interface StudentService {

    /**
     * SayHello
     * @return
     */
    String sayHello();
}


123456789

接口实现类

@Service
public class StudentServiceImpl implements StudentService {
    @Override
    public String sayHello() {
        return "Say Hello";
    }
}

1234567

最后在启动类中进行配置
第一种方式
这种方式通过SpringApplication的run方法返回一个ConfigurableApplicationContext对象,通过这个对象获取指定的对象即可

@SpringBootApplication
public class Application {


    public static void main(String[] args) {
        /**
         * Springboot程序启动后,返回值是ConfigurableApplicationContext,它也是一个Spring容器
         * 它其实相当于原来Spring容器中启动容器ClasspathXmlApplicationContext
         */

        SpringApplication.run(Application.class, args);

        //获取Springboot容器
        ConfigurableApplicationContext applicationContext = SpringApplication.run(Application.class, args);

        //从spring容器中获取指定bean对象
        StudentService studentService = (StudentService) applicationContext.getBean("studentServiceImpl");

        //调用业务方法
        String sayHello = studentService.sayHello();

        System.out.println(sayHello);

    }

}

1234567891011121314151617181920212223242526

这里不能使用注入对象,因为main的内部方法不可以调用实体类,需要创建另外一个方法调用,所以就是第二种方式了

第二种方式
通过对象注入,之后继承CommandLineRunner这个接口并且重写run实现方法
之后再run方法进行调用注入的对象
需要继承这个类,因为这个类有一些注解可以指引这些对象去使用
在这里插入图片描述

@SpringBootApplication  //开启spring配置
public class Application implements CommandLineRunner {

    @Autowired
    private StudentService studentService;

    public static void main(String[] args) {
        //SpringBoot启动程序,会初始化Spring容器
        SpringApplication.run(Application.class, args);
    }


    //重写CommandLineRunner类中的run方法
    @Override
    public void run(String... args) throws Exception {

        //调用业务方法
        String sayHello = studentService.sayHello("World");

        System.out.println(sayHello);
    }
}


1234567891011121314151617181920212223

5. 拓展

以下可做了解,不过还是要熟悉即可