本文主要是介绍imooc很有意思的springBoot入门教程笔记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前言
Spring Boot
是用来简化Spring
应用初始搭建以及开发过程的全新框架,被认为是SpringMVC
的接班人,和微服务紧密联系在一起。Spring Boot 简单实例Demo
SpringMVC 的优缺点
优点:
Spring Boot
适合快速开发,适合构建微服务系统。封装了经常使用的组件,比如MyBatis
,Hibernate
,MongoDB
等。- 纯
Java
的配置,简单方便。 - 配置Maven等构建工具后,
java -jar
进行部署比较简单。 Spring Boot
对自定义十分友好,可以配置在application.yml
或者Config
类,Spring Boot
的整体思想是有自定义的话,自定义优先,否则走默认配置。Spring Boot
使编码,配置,部署,监控变得简单起来。
缺点:
- 太方便,使得没有经验的新手根本不知道
Spring Boot
底层到底干了什么。集成度较高,使用过程中不容易了解底层。 - 相关学习文档少, 坑多。
- 太方便,使得没有经验的新手根本不知道
第一个Spring Boot的应用
- 首先创建一个
New Project
,要选择Spring Initializr,
然后Choose Initializr Service URL
应该选择Custom
, 正确的链接应该是http://start.spring.io/
,而不是https://start.spring.io/
。https
会造成我们访问失败!
2.相关配置,Type
我们选择Maven Project
3.选择Web
就行了。另外Spring Boot
的版本是1.5.8
4.Finished
。大功告成!
5.由于默认的setting.xml
配置,导致我们从远程下jar实在是太慢,所以我们要修改.m2
下面的setting.xml
文件,同时将setting.xml
原本指向C:\Users\Administrator\.m2\repository
的仓库地址,改成我们自定义的盘下面即可。
我的setting.xml是这样的,如果还是看不懂的话,请移步Setting.xml相关配置
<mirrors><mirror> <id>alimaven</id> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <mirrorOf>central</mirrorOf> </mirror> </mirrors
6.我们可以看到这个DemoApplication
类, 这是整个Spring Boot
应用的入口,有@SpringBootApplication
这个注解,显而易见。
@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}
}
7.接下来我们创建一个HelloController.java
, @RestController
这个注解的作用:声明这是一个Controller
类,返回json
。其实就是@ResponseBody
和@Controller
的结合体。
@RestController
public class HelloController {@RequestMapping(value = "/hello", method = RequestMethod.GET)public String say() {return "Hello, Spring Boot!";}
}
8.启动有3种方式。
(1)直接在Itellij IDEA
启动。
(2)在项目的根目录下,打开命令窗口,输入mvn spring-boot:run
(3)在项目的根目录下,打开命令窗口,输入mvn install
,让项目生成jar
包。
然后会发现target
包下面多了一个jar
包。
输入命令java -jar target/demo-0.0.1-SNAPSHOT.jar
9.我们就可以访问Spring Boot
应用了。
项目属性配置
1.我们可以在resources文件夹
下面建3个properties
, application-dev.properties
是开发环境下的配置文件。application-prod.properties
是应用环境下的配置文件。Spring Boot
默认读取的配置文件是application.properties
,我们只需要在application.properties
指定使用哪一个环境下的配置文件即可。比如:spring.profiles.active=dev
2.我们在application-dev.properties
,配置一些信息,让我们的Controller
类去读取配置信息。
server.port=8081
server.context-path=/girl
cupSize=A
height=160
content="cupSize: ${cupSize}, age: ${height}"
girl.cupSize=A
girl.height=160
3.Controller类读取配置信息,启动Spring Boot输出结果。
public class HelloController {@Value("${cupSize}")private String cupSize;@Value("${height}")private String height;@Value("${content}")private String content;@RequestMapping(value = "/display", method = RequestMethod.GET)public String display() {return "cupSize=" + cupSize + ", height=" + height;}@RequestMapping(value = "/content", method = RequestMethod.GET)public String displayContent() {return content;}
}
4.Controller
类读取配置信息带前缀的字符串,比如我们要读取girl.cupSize=A girl.height=160
这些带girl的配置信息,我们该怎么办呢。我们需要定义一个GirlProperties.java
。@ConfigurationProperties
代表我们要读取带什么前缀的配置信息,@Component
代表这个类已经在Spring配置文件中注册过。
@ConfigurationProperties(prefix = "girl")
@Component
public class GirlProperties {private String cupSize;private String height;public String getCupSize() {return cupSize;}public void setCupSize(String cupSize) {this.cupSize = cupSize;}public String getHeight() {return height;}public void setHeight(String height) {this.height = height;}
}
5.Controller
类读取GirlProperties
,我们要使用@Autowired
注入GirlProperties
这个类的实例,它是通过bean的类型注入的。启动Spring Boot应用,输出结果。
@RestController
public class HelloController {@Autowiredprivate GirlProperties girlProperties;@RequestMapping(value = "/properties", method = RequestMethod.GET)public String displayProperties() {return girlProperties.getCupSize() + girlProperties.getHeight();}
}
Controller的使用
1.尽量使用@GetMapping
和 @PostMapping
代替 @RequestMapping(value = "/xxxxx", method = RequestMethod.GET)
2.如果需要在Spring Boot
使用@Controller
,需要返回一个逻辑视图。比如
@Controller
public class DemoController {@RequestMapping(value = "/saylove", method = RequestMethod.GET)public String sayLove() {return "index";}
}
index.html
是在templates
文件夹下面的
3.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>girl</groupId><artifactId>demo</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>demo</name><description>Demo project for Spring Boot</description><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.8.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><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><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId><version>1.5.8.RELEASE</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
数据库操作
1.在application-dev.properties
配置数据连接配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/spring_boot
spring.datasource.username=root
spring.datasource.password=xiaoma96
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto
有4个属性: create
: 不管数据库原先有没有这个表,每次启动应用,都会drop这个表,然后再创建新的一张表。 update
: 如果数据库中有这个表且有数据,那么我会保留这张表,不会去删除它。 create-drop
: 应用停止的时候, 会把数据库里面这张表删除。 none
: 不产生任何行为。
2.什么是JPA
?JPA
的英文全称是Java Persistence API
定义了一系列对象持久化的标准,目前实现这个规范的产品有Hibernate
。
3.怎么去使用JPA
? 之前用过Liferay
技术, Liferay
通过ServiceBuilder
生成Service.xml
,在这个Service.xml
配置你需要创建数据库表的entity
信息,然后定义一些方法的字段。然后build一下。就会生成对应的CRUD
方法,很是智能。而且在下一次应用启动时,会生成对应的数据库表哟。如果需要定制化sql语句,只需要在finderImpl
和ServiceImpl
里面添加自己的方法,然后build
一下,重新生成接口。同样JPA
,简单的CRUD
我们不需要去写sql语句,只需要定义一个GirlRepository
的接口,继承JpaRepository<Girl, Integer>
就行了。需要定制化CRUD
,我们添加相应的方法就行了。
public interface GirlRepository extends JpaRepository<Girl, Integer> {public List<Girl> findByAge(Integer age);public List<Girl> findByCupSize(String cupSize);public List<Girl> findByName(String name);
}
4.定义RESTfulAPI
,开放CRUD
接口。增加,使用POST
, 查询使用GET
, 更新使用PUT
,删除使用DELETE
。
@RestController
public class GirlController {@Autowiredprivate GirlRepository girlRepository;/*** Queries all girls.* @return girls List queryed*/@GetMapping(value = "/girls")public List<Girl> girlList() {return girlRepository.findAll();}/*** Adds girl* @param name* @param cupSize* @param age* @return girl added*/@PostMapping(value = "/girls")public Girl girlAdd(@RequestParam("name") String name, @RequestParam("cupsize") String cupSize, @RequestParam("age") Integer age) {Girl girl = new Girl();girl.setAge(age);girl.setName(name);girl.setCupSize(cupSize);return girlRepository.save(girl);}/*** Finds girl by id* @param id* @return girl finded*/@GetMapping(value = "/girls/{id}")public Girl girlFindOne(@PathVariable("id") Integer id) {return girlRepository.findOne(id);}/*** Updates girl* @param id* @param name* @param cupSize* @param age* @return girl updated*/@PutMapping(value = "/girls/{id}")public Girl girlUpdateOne(@PathVariable("id") Integer id, @RequestParam("name") String name, @RequestParam("cupsize") String cupSize, @RequestParam("age") Integer age) {Girl girl = new Girl();girl.setCupSize(cupSize);girl.setName(name);girl.setAge(age);girl.setId(id);return girlRepository.save(girl);}/*** Deletes girl by id* @param id*/@DeleteMapping(value = "/girls/{id}")public void girlDeleteOne(@PathVariable("id") Integer id) {girlRepository.delete(id);}/*** Queries girls by name* @param name* @return girl list queryed*/@GetMapping(value = "/girls/name/{name}")public List<Girl> girlFindByName(@PathVariable("name") String name) {return girlRepository.findByName(name);}/*** Queries girls by age* @param age* @return girl list queryed*/@GetMapping(value = "/girls/age/{age}")public List<Girl> girlFindByAge(@PathVariable("age") Integer age) {return girlRepository.findByAge(age);}/*** Queries girls by cupsize* @param cupSize* @return girl list queryed*/@GetMapping(value = "/girls/cupsize/{cupsize}")public List<Girl> girlFindByCupSize(@PathVariable("cupsize") String cupSize) {return girlRepository.findByCupSize(cupSize);}
}
- 5.使用
Postman
软件,测试API
。在这里,我就测试一个查询api
,演示一下。
事务管理
1.什么是事务?事务是作为一个逻辑单元执行的一系列操作。它有4个特性
* 原子性:事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么全部失败。
* 一致性: 一旦事务完成,不管成功还是失败,系统必须确保它所建模的业务处于一致的状态,而不全是部分完成,或者是部分失败,在现实的数据不应有被破坏。
* 隔离性: 可能有许多事务会同时处理相同的数据, 因此每个事务都应该与其他事务隔离开,防止数据被破坏。
* 持久性: 一旦事务完成, 无论发生什么,系统发生错误,它的结果都不应该受到影响,这样就能从任何系统崩溃中恢复过来, 通常情况下,事务的记过被写到持久化存储器。
2.我们常用的几个事务:
* PROPAGATION_REQUIRED
: 如果存在一个事务,则支持当前的事务,如果没有则开启。
* PROPAGATION_SUPPORTS
: 如果存在一个事务,就支持当前事务, 如果没有事务,则以非事务执行。
* PROPAGATION_REQUIRES_NEW
: 启动一个新的事务,不依赖当前事务,当前事务挂起。
3.我们模拟一个事务的回滚,体现事务的原子性,第一个save
操作不会出现问题,第二个save
操作会抛出异常。但是不能部分成功,不能部分失败。这二个操作最终会被回滚。
@Service
public class GirlService {@Autowiredprivate GirlRepository girlRepository;@Transactionalpublic void insertTwo() {Girl girlA = new Girl("garrett-test", 18, "Z");girlRepository.save(girlA);Girl girlB = new Girl("mayday-test", 21, "BBBBBBBB");girlRepository.save(girlB);}
}@RestController
public class GirlController {@Autowiredprivate GirlService girlService;/*** Tests transaction*/@GetMapping(value = "/transaction")public void transactionTest() {girlService.insertTwo();}
}
4.启动应用,打开Postman
,测试API
。很显然,操作发生异常进行回滚,数据库未插入任何数据。
@Valid表单验证
在实体girl的age中声明如下:
@Min (value = 18 , message = "未成年少女禁止入门" ) |
在controller的验证方法中加入:
@PostMapping (value = "/girls" ) public Result girlAdd( @Valid Girl girl, BindingResult bindingResult) { if (bindingResult.hasErrors()) { return ResultUtil.error( 1 , bindingResult.getFieldError().getDefaultMessage()); } girl.setCupSize(girl.getCupSize()); girl.setAge(girl.getAge()); return ResultUtil.success(girlRepository.save(girl)); } |
@valid
用于验证参数的正确性,BindingResult对象用来显示错误信息!
AOP实现
(1)AOP处理请求(上)
前置通知(@Before):执行目标方法前拦截到的方法。只需要一个连接点,JoinPoint,即可获取拦截目标方法以及请求参数。
后置通知(@After):执行目标方法后拦截到的方法,不管方法是否抛出异常,都会走这个方法。只需要一个连接点,JoinPoint,即可获取当 前结束的方法名称。
返回通知(@AfterReturning):在方法正常执行通过之后执行的通知叫做返回通知。此时注意,不仅仅使用JoinPoint获取连接点信息,同时要在返回通知注解里写入,resut="result"。在切面方法参数中加入Object result,用于接受返回通知的返回结果。如果目标方法方法是void返回类型则返回NULL
异常通知(@AfterThrowing): 在执行目标方法过程中,如果方法抛出异常则会走此方法。和返回通知很相似,在注解中加入,throwing="ex",在切面方法中加入Exection ex用于接受异常信息
环绕通知(@Around):环绕通知需要携带ProceedingJoinPoint 这个类型的参数,环绕通知类似于动态代理的全过程ProceedingJoinPoint类型的参数可以决定是否执行目标函数环绕通知必须有返回值。其实就是包含了所有通知的全过程
首先,需要在pom中引入aop的包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
然后建立一个类,用
@Aspect@Component
做注解然后,在类中需要统一处理的方法,并用@before注释一下需要应用切面的包或者类或者方法
@Before("execution(public * com.quanxian.quanxian.controller.UserController.*(..))") public void log() { System.out.println("111111"); }
execution()是最常用的切点函数,其语法如下所示:
整个表达式可以分为五个部分:
1、execution(): 表达式主体。
2、第一个*号:表示返回类型,*号表示所有的类型。
3、包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,com.sample.service.impl包、子孙包下所有类的方法。
4、第二个*号:表示类名,*号表示所有的类。
5、*(..):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数。
(2)AOP请求处理(中)
在使用@before,@after的execution()函数时,会出现重复编写execution(),对此我们可以这么写
(3)AOP请求处理(下)
应用于记录http请求
@Before("log()")public void doBefore(JoinPoint joinPoint){ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = attributes.getRequest();//urllogger.info("url={}",request.getRequestURL());//methodlogger.info("method={}", request.getMethod());//iplogger.info("ip={}", request.getRemoteAddr());//类方法logger.info("class_method={}", joinPoint.getSignature().getDeclaringTypeName()+"."+ joinPoint.getSignature().getDeclaringType());//参数logger.info("args={}",joinPoint.getArgs());}
获取返回内容
@AfterReturning(returning = "object",pointcut = "log()")public void doAfterReturning(Object object){logger.info("response={}", object.toString());}
}
统一异常处理
这篇关于imooc很有意思的springBoot入门教程笔记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!