SpringBoot初始
第一天
第一章 SpringBoot概述
主要解决传统项目中存在的
- 配置文件
- 复杂依赖关系
1.1 什么是SpringBoot
1.2 为什么要学习SpirngBoot
第二章 SpringBoot的入门
2.1 快速构建(了解)
案例:
编写一套mvc程序,在浏览器上访问/hello的时候,页面显示:传智播客
Spring initializr介绍
Spring initializr是Spring官方提供的一个很好的工具,可以用来用来创建一个Spring boot的项目。可以选择使用Maven管理或者使用Gradle管理,根据需要选择Spring Boot的版本。
快速构建
定义controller
总结
SpringBoot程序搭建
- pom文件:
1.声明父工程 2.引入起步依赖 3.指定jdk版本1.8 - application.properties
- 启动类(引导类):
1.类上注解:@SpringBootApplication
2.main方法:SpringApplication.run(类.class, args) ;
2.2 SpringBoot依赖分析
Spring-boot-starter-parent
父工程:内部定义所有的版本号,并锁定
Spring-boot-starter-web
起步依赖:定义所用到的所有依赖jar包
总结
- 在spring-boot-starter-parent中定义了各种技术的版本信息,组合了一套最优搭配的技术版本。
- 在各种starter中,定义了完成该功能需要的坐标合集,其中大部分版本信息来自于父工程。
- 我们的工程继承parent,引入starter后,通过依赖传递,就可以简单方便获得需要的jar包,并且不会存在版本冲突等问题。
2.3 手动搭建SpringBoot(重点)
需求与分析
需求:实现和快速构建一模一样的功能
1.搭建SpringBoot环境
(1)pom文件(父工程,jdk版本,起步依赖)
(2)在resourelapplication.properties
(3)配置启动类(类上配置注解@SpringBootApplication,配置main方法)
2.
(1)配置controller注解
(2)配置请求对应的方法@RequestMapping
需求
搭建SpringBoot工程,定义HelloController.hello()方法,返回"Hello SpringBoot!"
实现步骤
1.创建Maven项目,导入SpringBoot起步依赖
(1)父工程
(2)起步依赖
(3)jdk1.8
2.定义配置文件:在resource下创建配置文件application.properties
3.配置引导类((启动类)
(1)类上配置注解
(2)配置main方法
4.配置controller并测试
代码实现
导入起步依赖
<!--父工程依赖-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>
<!--jdk版本1.8-->
<properties>
<java.version>1.8</java.version>
</properties>
<!--起步依赖-->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
定义controller
package cn.itcast.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloController {
@RequestMapping(value = "/hello2",method = RequestMethod.GET)
@ResponseBody
public String hello2() {
return "itcast is very good!";
}
}
编写引导类
package cn.itcast;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 引导类:
* 命名规则: xxxApplication
* 类上:@SpringBootApplication
* main:引导启动
* 业务代码:
* 需要放到引导类所在包及其子包下
*/
@SpringBootApplication
public class ConfigApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigApplication.class,args);
}
}
总结
- SpringBoot的引导类,是项目入口,运行main方法就可以启动项目。
- 使用SpringBoot和Spring构建的项目,业务代码编写方式完全一样。
- springboot内置了tomcat,默认端口:8080
第三章 SpringBoot的配置(重点)
springboot的配置文件两种类型:
- application.properties
- application.yaml(yaml--yml)
配置文件需要放置到resources目录下,并且以"application"命名,支持两种类型(properties,yaml(yml.yaml))
如果存在多个配置项: springboot会加载所有的配置文件,对于重名配置,他的优先级别如下:
properties>yml>yaml
3.1 SpringBoot中的配置文件
yaml
YAML全称是YAMLAin't Markup Language。YAML是一种直观的能够被电脑识别的的数据数据序列化格式,并且容易被人类阅读,容易和脚本语言交互的,可以被支持YAML库的不同的编程语言程序导入,比如:C/C++,Ruby, Python, Java, Perl, C#, PHP等。YML文件是以数据为核心的,比传统的xml方式更加简洁。YAML文件的扩展名可以使用.yml或者.yaml.
基本语法
- 大小写敏感
- 数据值前边必须有空格,作为分隔符
- "#"表示注释,从这个字符一直到行尾,都会被解析器忽略。
yaml数据格式
总结
3.2 回顾Spring注解
java配置主要靠java类和一些注解,比较常用的注解有:
- @Configuration:声明一个类作为配置类,代替xml文件
- @Bean:声明在方法上,将方法的返回值加入Bean容器,代替
标签 - @Value: 属性注入
3.3 读取配置文件内容(重点)
三种方式读取配置文件:
- @Value:配置到属性上,通过spel表达式获取配置项 @Value("${配置项名称}")
- Environment工具类:(1)注入工具类 (2)调用工具类方法:getPropertiy()
- @ConfigurationProperties:直接将配置项赋值到某个对象上
@Value
Environment
是springboot提供的对象,可以通过Environment获取所有的配置文件中的属性。
- 需要注入到程序中
- 调用对象的方法获取
@ConfigurationProperties
第三章 了解知识
3.1 bootstrap.yml和application.yml
- bootstrap.yml (bootstrap.properties):用来程序引导时执行,应用于更加早期配置信息读取,如可以使用来配置application.yml中使用到参数等
- application.yml (application.properties):应用程序特有配置信息,可以用来配置后续各个模块中需使用的公共参数等。
- bootstrap.yml先于application.yml 加载
bootstrap.yml可以理解为是针对于整个项目(或者说整个系统)的,而applicatoin.yml是针对于项目里的模块的。
3.2 SpringBoot多环境配置切换
第四章 SpringBoot启动流程(重点)
第四章补充 自动配置原理
4.1 了解@SpringBootApplication
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
4.2 默认配置原理
spring.factories
默认配置类
默认配置属性
4.3 总结
第五章 SpringBoot实战(重点)
完成SSM的案例:通过SpringBoot整合
案例:根据id查询用户
数据库:今日资料中有tb_user.sql
5.1 搭建环境
配置依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.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>
<!--单元测试-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!--事务:springboot中事务需要通过注解配置@Transactional-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--mybatis提供的起步依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
<!--lombok插件省略getset-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
<scope>provided</scope>
</dependency>
</dependencies>
添加配置文件
配置引导类
package cn.itcast.user;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class);
}
}
定义实体类
package cn.itcast.user.domain;
import lombok.Data;
import java.util.Date;
@Data
public class User {
private Integer id;
private String userName;
private String password;
private String name;
private Integer age;
private Integer sex;
private Date birthday; //出生日期
private String note; //备注
private Date created; //创建时间
private Date updated; //更新时间
}
配置controller
package cn.itcast.user.controller;
import cn.itcast.user.domain.User;
import cn.itcast.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@Slf4j
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(value = "/user/{id}",method = RequestMethod.GET)
@ResponseBody
public User findById(@PathVariable(value="id") Integer id) {
log.debug("用户输入的id="+id); // log.error, log.warn, log.info ,log.debug
return userService.findById(id);
}
@RequestMapping(value = "/hello",method = RequestMethod.GET)
@ResponseBody
public String hello() {
return "hello 黑马31";
}
}
配置service
5.2 整合springmvc
日志控制
springboot中内置了日志的处理。
日志使用
(1)需要在类上:@Slf4J(开启日志支持)
(2)调用log.xxx方法,输入日志
静态资源
拦截器(了解)
springboot中完成mvc拦截的功能
package cn.itcast.user.config;
import cn.itcast.user.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 注册拦截器
* 实现 WebMvcConfigurer 接口
* 重写 addInterceptors 方法
*/
@Configuration
public class MvcConfig implements WebMvcConfigurer {
/**
* registry : 注册器
* 所有的拦截器添加到注册器中即可
* 指定拦截的URL
* 不拦截的URL
*/
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/user/**")
.excludePathPatterns("/hello/**");
}
}
5.3 整合jdbc和事务
spring中的jdbc连接和事务是配置中的重要一环,在SpringBoot中该如何处理呢?答案是不需要处理,我们只要找到SpringBoot提供的启动器即可。
至于事务,SpringBoot中通过注解来控制。就是我们熟知的@Transactional
5.4 整合连接池
5.5 整合mybatis
dao接口
package cn.itcast.user.dao;
import cn.itcast.user.domain.User;
public interface UserDao {
User findById(Integer id);
}
映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.itcast.user.dao.UserDao">
<!--根据id查询-->
<select id="findById" resultType="cn.itcast.user.domain.User">
select * from tb_user where id=#{id}
</select>
</mapper>
配置文件
自动扫描
修改service实现类,注入dao查询
5.6 单元测试(了解)
(1)起步依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
(2)创建一个单元测试类
package cn.itcast.test;
import cn.itcast.user.MapperApplication;
import cn.itcast.user.dao.UserDao;
import cn.itcast.user.domain.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import tk.mybatis.mapper.entity.Example;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MapperApplication.class)
public class UserDaoTest {
@Autowired
private UserDao userDao;
@Test
public void test() {
Example example=new Example(User.class);
Example.Criteria criteria = example.createCriteria();
criteria.andEqualTo("id",1);
List<User> users = userDao.selectByExample(example);
System.out.println(users);
}
}
@RunWith(SpringRunner.class):指定单元测试运行环境
@SpringBootTest:配置引导类
5.7 通用mapper
使用步骤:
- 搭建SpringBoot环境
- 配置实体类,在实体类上通过注解配置类和数据库表的映射关系
- 配置dao接口(空接口);继承mapper接口,并提供泛型
- 注入dao接口,调用dao接口中的方法,完成基本CRUD
导入依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--web起步依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--事务相关-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--单元测试-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- 通用mapper不能和mybatis依赖共存 -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.5</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
<scope>provided</scope>
</dependency>
</dependencies>
配置实体类
在实体类上通过JPA注解的形式配置实体类和数据库表之间的映射关系
@Table @Id
配置dao接口
配置service和controller
略
配置SpringBoot
通用mapper中的方法介绍
package cn.itcast.test;
import cn.itcast.user.MapperApplication;
import cn.itcast.user.dao.UserDao;
import cn.itcast.user.domain.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import tk.mybatis.mapper.entity.Example;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MapperApplication.class)
public class UserDaoTest {
@Autowired
private UserDao userDao;
@Test
public void test() {
Example example=new Example(User.class);
Example.Criteria criteria = example.createCriteria();
//”id”表示的是实体类的属性名
criteria.andEqualTo("id",1);
List<User> users = userDao.selectByExample(example);
System.out.println(users);
}
}
第六章 经验值
使用通用mapper完成根据主键查询用户
6.1 已知代码
6.2 出现问题
6.3 问题分析
6.4 问题解答办法
第七章 原理分析经验分享
分析springboot项目中传递依赖的默认版本号和默认加载的配置文件
7.1 已知代码
7.2 问题分析
7.3 源码分析
第二天
第一章 SpringBoot整合常见框架(重点)
1.1 整合Thymeleaf
导入依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- 通用mapper -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.5</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
<scope>provided</scope>
</dependency>
<!--thymeleaf起步依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
解析器
基础语法
案例介绍
代码实现
(1)controller
package cn.itcast.controller;
import cn.itcast.domain.User;
import cn.itcast.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import cn.itcast.domain.User;
import cn.itcast.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
/**
* 通过controller进行页面跳转,并且在页面上展示对应的数据
* 1.将@RestController替换为@Controller
* 2.每个控制器方法的返回值,对应的页面路径
*/
//@RestController
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
//查询全部用户
@GetMapping("/findAll")
public String findAll(HttpServletRequest request) {
List list = userService.findAll();
request.setAttribute("list",list);
return "list";// 前缀 + 逻辑视图 + 后缀
}
/**
* rest风格,根据id查询用户
* 127.0.0.1:8080/user/5
* get : 查询1号用户
*
* 地址参数
* 不同的请求方式完成不同的业务处理
*/
@GetMapping("/{id}")
public String findById(@PathVariable Integer id,HttpServletRequest request) {
User user = userService.findById(id);
request.setAttribute("user",user);
return "view";// 前缀 + 逻辑视图 + 后缀
}
}
(2)service
package cn.itcast.service.impl;
import cn.itcast.dao.UserDao;
import cn.itcast.domain.User;
import cn.itcast.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
public List<User> findAll() {
return userDao.selectAll();
}
@Override
public User findById(Integer id) {
return userDao.selectByPrimaryKey(id);
}
}
(3)dao
package cn.itcast.dao;
import cn.itcast.domain.User;
import tk.mybatis.mapper.common.Mapper;
/**
* 继承父接口 Mapper<实体类>
* 通用mapper提供了基础的CRUD方法,内部自动的拼接SQL语句并发送
* 对于复杂查询:延用mybatis的使用习惯
*/
public interface UserDao extends Mapper<User> {
}
(4)domain
package cn.itcast.domain;
import lombok.Data;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;
/**
* 通用mapper:
* 在实体类上配置表,字段映射关系
* @Table
* @Id
*/
@Data
@Table(name="tb_user")
public class User {
@Id
private Integer id;
private String userName;
private String password;
private String name;
private Integer age;
private Integer sex;
private Date birthday; //出生日期
private String note; //备注
private Date created; //创建时间
private Date updated; //更新时间
}
(5)引导类
(6)application.yml
server:
port: 8088
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql:///springbootdemo
driver-class-name: com.mysql.jdbc.Driver
总结
1.2 整合RabbitMQ
搭建环境
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
配置消息生产者
(1)创建生产者工程,配置SpringBoot整合RabbitMQ
spring:
rabbitmq:
virtual-host: HL #虚拟主机
username: HL
password: 123456
host: 127.0.0.1
port: 5672
server:
port: 8088
(2)配置生产者工程,创建引导类
(3)在生产者工程,以单元测试发送消息
package cn.itcast;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ProducerTest {
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void testSend() throws Exception {
//第一个参数:交换机名称
//第二个参数:路由key(消息分组id)
//第三个参数:发送的消息
rabbitTemplate.convertAndSend("springboot-rabbi2","a.b","802不见不散");
}
}
配置消息消费者
(1)创建消费者工程引入依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
(2)配置SpringBoot整合RabbitMQ
spring:
rabbitmq:
virtual-host: HL #虚拟主机
username: HL
password: 123456
host: 127.0.0.1
port: 5672
server:
port: 8089
(3)消费者工程,配置引导类
(4)消费者工程配置监听器
package cn.itcast.listener;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* 消息监听器
* 当队列中有最新消息时,会自动触发监听器中的方法。
* */
@Component
public class MessageListener {
/**
* 返回值:没有返回值
* 参数:参数类型和生产者发送消息类型一致
* @RabbitListener : 配置监听的队列,交换机和路由key之间的绑定关系
* bindings: 配置绑定关系
* @QueueBinding 注解
* value :配置队列
* @Queue:
* value:队列名称
* durable:是否持久化
* exchange:配置队列绑定的交换机
* @Exchange
* value: 交换机名称(和生产者一致)
* type:配置类型(faount,direct,topic)
* key : 当前队列可以处理的路由key(分组名称)
*/
@RabbitListener(
bindings =@QueueBinding(
value = @Queue(value = "quqeue1",durable = "true"),
exchange = @Exchange(value = "springboot-rabbi2",type = "topic"),
key="#.#"
)
)
public void messag(String message) {
System.out.println(message);
}
}
1.3 整合Redis
1、导入起步依赖
2、在application.yml 配置redis访问信息
3、测试(通过注入RedisTemplate,操作redis数据库)
- 导入了SpringData-redis,spring封装操作redis的工具(jedis)
- 内置了一个对象RedisTemplate(StringRedisTemplate)
- opsForXXX
搭建环境
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>
Springboot整合redis的配置
测试
package cn.itcast;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RedisApplication {
public static void main(String[] args) {
SpringApplication.run(RedisApplication.class,args);
}
}
package cn.itcast.test;
import cn.itcast.RedisApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Map;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = RedisApplication.class)
public class RedisTest {
/**
* 此对象默认调用java的序列化接口对传输的数据进行序列化操作
* java底层的序列化操作效率低
* @Autowired
* private RedisTemplate redisTemplate;
*/
/**
* 专门用于操作String类型数据的工具类
* 需要将传输的对象,转化为json字符串的形式发送
*/
/**
* springdataredis中,内置了RedisTemplate
* 1、注入redistemplte对象
* 2、调用opsForxxx方法操作
* 在RedisTemplate中,将数据经过java序列化转化为byte数组,传递到redis存储
* 1、数据的序列化和反序列化
* 2、浪费效率
* 3、java序列化效率极低
* 企业中开发:RedisTemplate的子类StringRedisTemplate
* 只能操作String类型的数据结构
* eg:User对象 -- json -- 调用
*
*/
@Autowired
private StringRedisTemplate redisTemplate;
@Test
public void test() {
//存入数据
//redisTemplate.opsForValue().set("key1","heima115");
//取出基本数据
//String value = redisTemplate.opsForValue().get("key1");
//System.out.println(value);
//redisTemplate.opsForValue().set("key2","heima115",10, TimeUnit.SECONDS);
// Map map = new HashMap();
// map.put("name","zhangsan");
// map.put("age","12");
// redisTemplate.opsForHash().putAll("user",map);
//System.out.println(redisTemplate.opsForHash().get("user","name"));
Map<Object, Object> map = redisTemplate.opsForHash().entries("user");
map.forEach((key,value)-> System.out.println(key+"--"+value));
}
}
第二章 SpringBoot核心原理
2.1 @Conditional注解
Condition是在Spring4.0增加的条件判断功能,通过这个可以功能可以实现选择性的创建Bean操作
基本使用
package cn.itcast.domain;
/**
* 需要交给容器管理
* 模拟第三方的对象:datasource
*/
public class User {
}
package cn.itcast.config;
import cn.itcast.condition.MyCondition;
import cn.itcast.domain.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.type.AnnotatedTypeMetadata;
/**
* 配置类
*/
@Configuration
public class UserConfig {
/**
* 创建对象User,将User对象存入到spring容器中
* @Conditional : 条件注解
* 执行@Bean的条件
* value : 需要匹配的条件
*/
@Bean
@Conditional(MyCondition.class)
public User user() {
return new User();
}
}
package cn.itcast.condition;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
/**
* 自定义条件
* 实现接口Condition
*/
public class MyCondition implements Condition {
/**
* 条件匹配
*/
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
boolean flag = true;
/**
* 判断工程中是否具有Jedis对象
*/
try {
Class.forName("redis.clients.jedis.Jedis");
} catch (ClassNotFoundException e) {
flag = false;
}
return flag;
}
}
自定义
package cn.itcast.anno;
import cn.itcast.condition.MyCondition;
import org.springframework.context.annotation.Conditional;
import java.lang.annotation.*;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
//继承@Conditional注解
@Conditional(MyCondition.class)
public @interface MyConditional {
String name(); //需要额外添加的条件
}
package cn.itcast.condition;
import cn.itcast.anno.MyConditional;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
import java.util.Map;
/**
* 判断是否导入了jedis的jar包
* 1、通过反射创建Jedis对象
* 2、如果正常执行:返回true
* 3、如果抛出异常:返回false
*/
public class MyCondition implements Condition {
/**
* 条件匹配
*/
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
/**
* 获取注解上的所有参数
* annotatedTypeMetadata :注解对象的元数据
* map
* 注解中的属性名,value
*/
Map<String, Object> map = metadata.getAnnotationAttributes(MyConditional.class.getName());
String className = (String)map.get("className");;
boolean rtn = true;
try {
Class.forName(className);
}catch (Exception e) {
rtn=false;
}
return rtn;
}
}
总结
2.2 @Import注解
@Enable*注解
SpringBoot中提供了很多Enable开头的注解,这些注解都是用于动态启用某些功能的。而其底层原理是使用@lmport注解导入一些配置类,实现Bean的动态加载。
@Import注解语法
@Enable*底层依赖于@Import注解导入一些类,使用@Import导入的类会被Spring加载到IOC容器中。而@lmport提供4中用法:
- 导入Bean
- 导入配置类
- 导入ImportSelector 实现类。一般用于加载配置文件中的类
- 导入lmportBeanDefinitionRegistrar 实现类。
package cn.itcast;
import cn.itcast.domain.User;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;
@SpringBootApplication
//@Import(User.class) //直接创建对象存入容器
//@Import(UserImportConfig.class) //导入其他的配置类 == @Configuration
//@Import(MyImportelector.class)
//@Import(MyImportBeanDefinitionRegistrar.class)
@EnableUser
public class AnnotationApplication {
public static void main(String[] args) {
//返回值:容器对象
ConfigurableApplicationContext ac = SpringApplication.run(AnnotationApplication.class, args);
//获取对象
User user = ac.getBean(User.class) ;//通过类型从容器中获取对象
System.out.println(user);
}
}
导入Bean对象
导入配置类
导入ImportSelector实现类
(1)编写ImportSelector 实现类
package cn.itcast.imp;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
/**
* 自定义Importelector
*/
public class MyImportelector implements ImportSelector {
/**
* 1.springboot启动的时候加载import注解
* 2.找到注解上配置的MyImportelector
* 3.制定MyImportelector的selectImports获取返回值数据
* 4.返回值数据类的全类名
* 5.根据类名创建对象
* 6.存入spring容器
*
* 需要制定创建的对象
*/
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
//在返回值中配置需要自动创建对象的全类名数组
return new String[]{"cn.itcast.domain.User"};
}
}
导入ImportBeanDefinitionRegistrar实现类
(1)编写lmportBeanDefinitionRegistrar 实现类
package cn.itcast.imp;
import cn.itcast.domain.User;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/**
* 注册对象
* 创建对象交给spring容器
*/
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//spring中定义对象的工具类 相当于创建User对象
AbstractBeanDefinition definition = BeanDefinitionBuilder.genericBeanDefinition(User.class).getBeanDefinition();
//注册:将对象注册到spring容器 相当于配置id,存入User对象
registry.registerBeanDefinition("user",definition);
}
}
自定义EnableUser注解
2.3 @EnableAutoConfiguration注解
第三章 自定义启动器(自动配置)
3.1 分析Mybatis启动器
3.2 案例与分析
3.3 环境搭建
配置autoconfigure模块
(1)导入依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
(2)配置工具类
package com.itheima.email.utils;
import javax.mail.Address;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;
public class EmailTemplate {
private String host; //smtp服务器地址 smtp.sina.com
private String from; //邮件的发送人邮件地址
private String password; //发送人的密码
public EmailTemplate(String host, String from, String password) {
this.host = host;
this.from = from;
this.password = password;
}
/**
*
* @param to 收件人
* @param subject 主题
* @param content 内容
* @throws Exception
*/
//实现邮件发送的方法
public void sendMsg(String to ,String subject ,String content) throws Exception{
//1.设置参数
Properties props = new Properties();
props.setProperty("mail.smtp.host", host); //设置主机地址 smtp.qq.com smtp.163.com
props.setProperty("mail.smtp.auth", "true");//认证
//2.产生一个用于邮件发送的Session对象
Session session = Session.getInstance(props);
//3.产生一个邮件的消息对象
MimeMessage message = new MimeMessage(session);
//4.设置消息的发送者
Address fromAddr = new InternetAddress(from);
message.setFrom(fromAddr);
//5.设置消息的接收者
Address toAddr = new InternetAddress(to);
//TO 直接发送 CC抄送 BCC密送
message.setRecipient(MimeMessage.RecipientType.TO, toAddr);
//6.设置主题
message.setSubject(subject);
//7.设置正文
message.setText(content);
//8.准备发送,得到火箭
Transport transport = session.getTransport("smtp");
//9.设置火箭的发射目标
transport.connect(host, from, password);
//10.发送
transport.sendMessage(message, message.getAllRecipients());
//11.关闭
transport.close();
}
}
(3)配置邮件配置信息配置类
package com.itheima.email.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "email")
public class EmailProperties {
private String from;
private String host;
private String password;
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
(4)自动装配类
自动装配配置类中:创建邮件发送的工具类,交给spring容器管理
package com.itheima.email.config;
import com.itheima.email.utils.EmailTemplate;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
//相当于,在EmailProperties上面配置了@Component
@EnableConfigurationProperties(value=EmailProperties.class)
public class EmailConfig {
@Bean
public EmailTemplate emailTemplate (EmailProperties ep) {
return new EmailTemplate(ep.getHost(), ep.getUsername(), ep.getPassword());
}
}
配置starter模块
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>cn.itcast</groupId>
<artifactId>mail-spring-boot-autoconfigure</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
3.4 测试