- 参考文章
- Spring
- Spring Boot体系结构
- 前后端分离项目
- SpringBoot非web项目
- 注解
- controller(@Controller默认多例)层
- @RestController和@RequestMapping使用@PathVariable:获取url中的数据@RequestParam :获取请求参数的值@GetMapping ,当然也有对应的Post等请求的简化写法">@RestController和@RequestMapping使用@PathVariable:获取url中的数据@RequestParam :获取请求参数的值@GetMapping ,当然也有对应的Post等请求的简化写法
- @Component:
- 通用注解,可标注任意类为Spring组件。如果一个Bean不知道属于哪层,可以使用@Component注解
- 默认实例化的对象是单例,如果想声明成多例对象可以使用@Scope(“prototype”)
- controller(@Controller默认多例)层
- Dao层
- APP层
- 系统实战
- 项目部署
- 第三方集成
- 读取配置文件
- 疑难杂症
- 4、mysql增删查改返回值
- 5、mybatis多表查询返回结果集
- 6、No bean named ‘xxx’ available异常,
- 完美修改项目名称">7、完美修改项目名称
- 8、读取
application.properties
文件的中文乱码
参考文章
- 1.送给 Java 程序员的 Spring 学习指南 -InfoQ
- 2.看起来很长但还是有用的Spring学习笔记 - 泊浮说 - SegmentFault 思否
- 3.Spring常见问题总结(补充版)
- 4.面试官:“谈谈Spring中都用到了那些设计模式?”。
- 5、Spring实战第五版https://potoyang.gitbook.io/spring-in-action-v5/
- 6、初始化Spring项目
- 7、基于 Spring Boot 2.X 的 Spring Boot 深入学习项目。艿艿的 Spring Boot 系列
- 8、SpringBoot官方API
-
学习Spring之前具备的基础
Spring
IOC思想
概念
IOC(Inversion of Control) :程序将创建对象的权利交给框架。
- 之前在开发过程中,对象实例的创建是由调用者管理的,代码如 下:
- 1 浪费资源:StudentService调用方法时即会创建一个对象,如果不断调用方法则会创建大量StudentDao对象。
- 2 代码耦合度高:假设随着开发,我们创建了StudentDao另一个 更加完善的实现类StudentDaoImpl2,如果在StudentService 中想使用StudentDaoImpl2,则必须修改源码。
IOC思想是将创建对象的权利交给框架,框架会帮助我们创建对象,分配对象的使用,控制权由程序代码转移到了框架中,控制权 发生了反转,这就是Spring的IOC思想。而IOC思想可以完美的解决 以上两个问题。
容器接口
BeanFactory:BeanFactory是Spring容器中的顶层接口,它可 以对Bean对象进行管理。
ApplicationContext:ApplicationContext是BeanFactory的子 接口。它除了继承 BeanFactory的所有功能外,还添加了对国际 化、资源访问、事件传播等方面的良好支持。 ApplicationContext有以下三个常用容器实现类:
- ClassPathXmlApplicationContext:该类可以从项目中读取配置文件
- FileSystemXmlApplicationContext:该类从磁盘中读取配置文件
- AnnotationConfigApplicationContext:使用该类不读取配置文件,而是会读取注解
Spring Boot体系结构
SpringBoot是Spring框架的模块。它用于轻松创建独立的生产级基于Spring的应用程序。它是在核心Spring框架的顶部开发的。
SpringBoot遵循一个分层的体系结构,其中每一层都与它的直接下层或上层(层次结构)进行通信。
之前了解 SpringBoot Architecture 后,我们必须了解其中的不同层和类。 SpringBoot中有四个层,如下所示:
展示层
- 业务层
- 持久层
- 数据库层
- 展示层: 表示层负责处理HTTP请求,将JSON参数转换为对象,并对请求进行身份验证并将其传输到业务层。简而言之,它由视图即前端部分组成。
- 业务层: 业务层处理所有业务逻辑 >。它由服务类组成,并使用数据访问层提供的服务。它还执行授权和验证。
- 持久层: 持久层包含所有存储逻辑,并将业务对象与数据库行进行相互转换。
- 数据库层: 在数据库层中, CRUD (创建,检索,更新,
- 现在我们有验证器类,视图类和实用程序类。
- Spring Boot使用类似于Spring MVC,Spring Data等的所有模块。SpringBoot的体系结构与Spring MVC的体系结构相同,不同之处在于: 不需要 DAO 和 DAOImpl 类在Spring启动中。
- 创建数据访问层并执行CRUD操作。
- 客户端发出HTTP请求(PUT或GET)。请求发送到控制器,然后控制器映射该请求并进行处理。之后,如果需要,它将调用服务逻辑。
- 在服务层中,所有业务逻辑都将执行。它对通过类映射到JPA的数据执行逻辑。
-
前后端分离项目
Spring Boot前后端交互json
一种是后端接口直接返回页面,后端页面渲染返回
另外一种是返回JSON数据。微服务接口,前后端分离项目,手机app
postman
- 专业的接口测试工具去测试数据。
- PostMan工具,
- 作用是模拟浏览器请求,拼装参数和格式化json响应结果。
Postman能够发送任何类型的HTTP请求(GET, HEAD, POST,PUT..),附带任何数量的参数和HTTP headers。支持不同的认证机制(basic, digest,OAuth),接收到的响应语法高亮(HTML,JSON或XML)。
基于postman的RESTFUL接口测试
JSON解析-fastjson
pom.xml依赖
<!-- fastjson坐标,处理json -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.79</version>
</dependency>
RESTful API
REST,表现层状态转移(representation state transfer)。 REST 是属于 WEB ⾃身的⼀种架构⻛格,是在 HTTP 1.1 规范下实现的。 简单来说,就是用URI表示资源,用HTTP方法(GET, POST, PUT, DELETE)表征对这些资源的操作。我们使用REST应用程序来开发和设计网络应用程序。它生成对数据执行CRUD操作的HTTP请求。
- Resource: 资源,即数据,存在互联网上的可被访问的实体
- Representation: 数据的某种表现形式,如HTML, JSON。
- State Transfer:状态变化,HTTP方法实现
参考文章
当然,现实世界中,可能并不一定严格地按照数据库操作的CRUD来理解API,比如,你有一个登录的API /login 你觉得这个API应该是 GET ,POST,PUT 还是 PATCH ?登录的时候用户需要输入用户名和密码,然后跟数据库里的对比(select操作)后反回一个登录的session token,然后这个token作为用户登录的状态令牌。如果按上面表格来说,应该是 select 操作进行 GET ,但是从语义上来说,登录并不是查询信息,应该是用户状态的更新或是新增操作(新增session),所以还是应该使用 POST,而 /logout 你可以使用 DELETE 。这里相说明一下,不要机械地通过数据库的CRUD来对应这些动词,很多时候,还是要分析一下业务语义。
陈浩RestAPI使用
前后端参数的传递
控制层(controller)
@RequestBody注解通过Map或JSONObject接收(太麻烦,既要从Map中取值,取完值后又要封装到Map)
@RequestParam注解接收**单个属性**(推荐)
--语法:@RequestParam(value=”参数名”,required=”true/false”,defaultValue=””)
1、value:参数名,
2、required:是否包含该参数,默认为true,表示该请求路径中必须包含该参数,如果不包含就报错。 可以通过**@RequestParam(required = false)设置为非必传**
服务层(service)
- service将控制层接受到的参数封装到map或javabean中再传递到dao层(即使是controller层用Map接收,service层中也要从Map中取值)
- service中也可以直接将参数分别传递到dao层
数据访问层(dao)
通过@Param
注解接收service层中的 (单个属性/Map/JavaBean)SpringBoot非web项目
App项目启动类改造
方法一:手动获取Spring容器中的Bean
```java /**- 创建非Web项目的第一种方式
*/
@SpringBootApplication
public class Application {
public static void main(String[] args) {
/**
- SpringBoot程序启动后,返回值是ConfigurableApplicationContext,它也是一个Spring容器
- 它其实相当于原来Spring容器中的ClasspathXmlApplicationContext */ //获取SpringBoot容器 ConfigurableApplicationContext applicationContext = SpringApplication.run(Application.class, args); //从Spring容器中获取指定的对象 HelloService helloService = (HelloService) applicationContext.getBean(“helloService”); //调用业务方法 String hi = helloService.getHi(); System.out.println(hi); }
- 创建非Web项目的第一种方式
*/
@SpringBootApplication
public class Application {
public static void main(String[] args) {
}
<a name="a3emA"></a>
### 方法二:继承CommandLineRunner接口,使用自动注入特性
```java
/**
* 创建非项目的第二种方式
*/
@SpringBootApplication
public class NotwebApplication implements CommandLineRunner{
@Autowired
private HelloService helloService;
public static void main(String[] args) {
SpringApplication.run(NotwebApplication.class, args);
}
@Override
public void run(String[] args) throws Exception {
String hi = helloService.getHi();
System.out.println(hi);
}
}
框架支持添加
右键项目,
Add Framework Support
,选择Maven
注解
我们可以把@SpringBootApplication看作是@Configuration、@EnableAutoConfiguration、@ComponentScan注解的集合。 根据Spring Boot官网,这三个注解的作用是: @EnableAutoConfiguration:启用Spring Boot的自动配置机制。 @ComponentScan:扫描被@Component(@Service,@Controller)注解的bean,注解默认会扫描该类所在包下的所有类。 @Configuration:允许Spring上下文中注册额外的bean或导入其他配置类。
2.@Autowired: 自动导入对象到类中,被注入进的类要被Spring容器管理。controller(@Controller默认多例)层
@RestController和@RequestMapping使用@PathVariable:获取url中的数据@RequestParam :获取请求参数的值@GetMapping ,当然也有对应的Post等请求的简化写法
**@RequestMapping**
:配置url映射**@RestController**:
@RestController注解是@Controller和@ResponseBody的合集,主要用于返回JSON数据或XML数据。- @Controller: 对应Spring MVC控制层,主要返回页面。修饰class,⽤来创建处理http请求的对象。
- @ResponseBody ,它将方法返回值绑定到响应主体。它告诉Spring Boot Framework将返回的对象序列化为JSON和XML格式。
@Component:
通用注解,可标注任意类为Spring组件。如果一个Bean不知道属于哪层,可以使用@Component注解
默认实例化的对象是单例,如果想声明成多例对象可以使用@Scope(“prototype”)
@Service(默认单例): 对应服务层,主要涉及一些复杂的逻辑。Dao层
1、@Repository(默认单例): 对应持久层即Dao层,主要用于数据库相关操作。
2、Mybaties Annotation
@Mapper// 标志为 Mybatis 的 Mapper
@Select
模糊查询符号:
@Select(“ select from weather.user where user_name=**#{name}**
“)
@Select(“select from weather.user where user_name=**'${userName}'**
“)@Results和@Result
Results中可以包含多个Result注解。其中每个Result注解设置javaBean对象和数据库表映射关系。column数据库字段。property是Bean属性。(如果数据库与javaBean对象名字相同或着设置了自动转驼峰全局配置不用写)@Param (一个参数可以不用)
如果你的映射器的方法需要多个参数, 这个注解可以被应用于映射器的方法 参数来给每个参数一个名字。否则,多 参数将会以它们的顺序位置来被命名 (不包括任何 RowBounds 参数) 比如。 #{param1} , #{param2} 等 , 这 是 默 认 的 。 使 用 @Param(“person”),参数应该被命名为 #{person}。
@RequestBody
7.@Configuration: 一般用来声明配置类,可以使用@Component注解代替,不过用@Configuration注解声明配置类更加语义化。
APP层
将Spring Boot应用打成WAR包,然后部署到外部容器运行,需要在应用中继承SpringBootServletInitializer类,然后重写config方法,将其指向应用启动类。
public class HwDataServerApplication extends SpringBootServletInitializer{
public static void main(String[] args) {
SpringApplication.run(HwDataServerApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(HwDataServerApplication.class);
}
}
系统实战
数据库设计
需求
学生端口:学生信息查询(密码、id)
教职工端口:学生列表查询,学生选课,老师成绩录入(录入成绩 同时更新到 学生的总学分),教师查询
实体
- 学生(students):学号(s_id)、姓名(s_name)、班级(s_class)、性别(s_gender)、专业(s_major)、学分(credit_points)
- 老师(teachers):教师编号(t_id)、姓名(t_name)、学院(t_school)
- 课程(courses):课程编号(c_id)、教师编号(t_id)、课程名称(c_name)、课程学分(credit_point)
成绩(scores):学号(s_id)、课程编号(c_id)、成绩(score)
实体关系
学生:课程 = m : n , 关系表:成绩
-
项目部署
项目打包
Maven项目
多环境配置
SpringBoot多环境配置,配置文件名为:
application-环境名.yml
JDK运行SpringBoot的jar包时选择环境,命令为:
java -jar jar包名 --spring.profiles.active=环境名
Spring Boot配置热部署(IDEA2021.3 开发)
热部署,就是在应用正在运行的时候升级软件,却不需要重新启动 应用。即修改完代码后不需要重启项目即可生效。在SpringBoot 中,可以使用DevTools工具实现热部署
添加依赖
<!-- 热部署工具 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency>
IDEA配置
File Setting ->Buile,Execution,Deployment-> Compiler ->勾选Build project automatically ->
->Advanced Settings ->勾选 Allow auto-make to start even if developed application is currently running->Apply第三方集成
日志
Mybaties框架
导入依赖
<!--mysql连接--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <!--Mybatis集成--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.2</version> </dependency>
邮件
激活邮箱授权码
163邮箱授权码:QZBGWKDQCCFXBBBP
qq邮箱授权码:iwbdfjbeeqmdecbf导入依赖
<!--邮件--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency>
application.properties
##邮件发送需要的配置 ## smtp服务主机 qq邮箱为smtp.qq.com spring.mail.host=smtp.163.com ## 服务协议 spring.mail.protocol=smtp ## 编码集 spring.mail.default-encoding=UTF-8 ## 发送邮件的账户(注:可以是普通的手机号或登录账号,并非一定是邮箱) spring.mail.username=yazhai233 ## 授权码 spring.mail.password=QZBGWKDQCCFXBBBP spring.mail.test-connection=true ## 邮件发信人(即真实邮箱) spring.mail.properties.from=yazhai233@163.com ## 邮件标题(日志上传——天气监控,中文转Unicode码) spring.mail.properties.subject=\u65e5\u5fd7\u4e0a\u4f20\u2014\u2014\u5929\u6c14\u76d1\u63a7!!! spring.mail.properties.mail.smtp.auth=true ##启动TLS加密 spring.mail.properties.mail.smtp.starttls.enable=true spring.mail.properties.mail.smtp.starttls.required=true ##设置超时时间 spring.mail.properties.mail.smtp.connectiontimeout=5000 spring.mail.properties.mail.smtp.timeout=3000 spring.mail.properties.mail.smtp.writetimeout=5000
spring-boot-starter-mail
API使用JavaMailSenderImpl
什么是JavaMailSender和JavaMailSenderImpl?
JavaMailSender和JavaMailSenderImpl 是Spring官方提供的集成邮件服务的接口和实现类,以简单高效的设计著称,目前是Java后端发送邮件和集成邮件服务的主流工具。如何通过JavaMailSenderImpl发送邮件?
非常简单,直接在业务类注入JavaMailSenderImpl并调用send方法发送邮件。其中简单邮件可以通过SimpleMailMessage来发送邮件,而复杂的邮件(例如添加附件)可以借助MimeMessageHelper来构建MimeMessage发送邮件。@Service public class MailService { @Resource JavaMailSenderImpl mailSender; public void baseServer() { //创建简单邮件消息 SimpleMailMessage message = new SimpleMailMessage(); //获取全局配置文件中 spring.mail前缀的 properties String from = mailSender.getJavaMailProperties().getProperty("from"); message.setSubject("邮件测试"); message.setFrom(from); message.setTo("2087886525@qq.com"); message.setSentDate(new Date()); message.setText("hello world"); //因为发送邮件是一种耗时的任务,从几秒到几分钟不等,因此,异步发送是保证页面能快速显示的必要措施 //启动一个新线程来异步发送邮件 new Thread(()->{ mailSender.send(message); }).start(); }
为什么JavaMailSenderImpl 能够开箱即用 ?
所谓开箱即用其实就是基于官方内置的自动配置,翻看源码可知晓邮件自动配置类(MailSenderPropertiesConfiguration) 为上下文提供了邮件服务实例(JavaMailSenderImpl)。具体源码如下:
@Configuration
@ConditionalOnProperty(prefix = "spring.mail", name = "host")
class MailSenderPropertiesConfiguration {
private final MailProperties properties;
MailSenderPropertiesConfiguration(MailProperties properties) {
this.properties = properties;
}
@Bean
@ConditionalOnMissingBean
public JavaMailSenderImpl mailSender() {
JavaMailSenderImpl sender = new JavaMailSenderImpl();
applyProperties(sender);
return sender;
}
其中MailProperties是关于邮件服务器的配置信息,具体源码如下:
@ConfigurationProperties(prefix = "spring.mail")
public class MailProperties {
private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
private String host;
private Integer port;
private String username;
private String password;
private String protocol = "smtp";
private Charset defaultEncoding = DEFAULT_CHARSET;
private Map<String, String> properties = new HashMap<>();
}
导入本地jar包
jar包结构
## []表示directory
[org]
[META-INF]
[BOOT-INF]
[lib](打包后,导入的jar所在目录)
[classes]
引入本地jar包方法
resources
下创建文件夹jar
用来存放本地jar包,并右键add as a library
pom
文件添加依赖<dependencies> <!--导入本地jar包--> <!--code.jar--> <dependency> <!--这三个属性自己定义即可--> <groupId>code.java</groupId> <artifactId>code-java</artifactId> <version>1.0</version> <!--jar包适用范围--> <scope>system</scope> <!--指定本地jar包路径--> <systemPath>${project.basedir}/src/main/resources/jar/code.jar</systemPath> </dependency> <!--导入本地jar包,End--> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <!--mvn clean package打jar包之后,BOOT-INF\lib里面并不会出现本地jar包, 需要configuration属性配置 来将 scope为system的jar包 一并加载到打包到生成的BOOT-INF\lib目录中--> <configuration> <includeSystemScope>true</includeSystemScope> </configuration> </plugin> </plugins> </build>
读取配置文件
//读取application.properties的属性 @Value("${spring.mail.properties.from}") protected String from;
疑难杂症
1、POSTMAN测试工具
```java 遇到的错误:Content type ‘text/plain;charset=UTF-8’ not supported
解决方法:原因是数据传输格式错误。因为发送的数据是json格式的,而postman默认是text格式,所以改成选择json样式。 ```
2、Dao层的User和List等等对象都不用实例化
3、对象的属性名与表的属性名称需要逐一对应
法一:
全局配置(application.properties)下划线转驼峰配置
mybatis.configuration.map-underscore-to-camel-case=true
ep:user_name 对应 userName
法二:
@Results和@Result
Results中可以包含多个Result注解。其中每个Result注解设置javaBean对象和数据库表映射关系。column数据库字段。property是Bean属性。(如果数据库与javaBean对象名字相同或着设置了自动转驼峰全局配置不用写)
4、mysql增删查改返回值
5、mybatis多表查询返回结果集
6、No bean named ‘xxx’ available异常,
大小写的问题
Springboot 在bean的名称返回时有个规则,当类名开头为连续至少两个大写字母时,会保留原有类名返回,当类名开头只有一个大写字母时,会返回小写开头的类名。例如类名为ExampleClass,在获取名称应该使用exampleClass,而如果类名为EXAMPLEClass,则获取名称时还是使用EXAMPLEClass。
7、完美修改项目名称
8、读取application.properties
文件的中文乱码
原因:
spring boot项目默认的加载application.properties
是通过字符集ISO-8859-1载入的