SpringBoot
- 1. springboot简介
- 2. 本地maven方式创建springboot项目
- 3. springboot场景启动器原理
- 4. 联网创建springboot项目
- 5. springboot启动+自动配置原理
- 6. springboot-配置文件
- 7. springboot-ssm整合
- 8. springboot-ssm 整合druid
- 9.springboot-单元测试的使用
- 10.springboot-整合事务
- 11.springboot-整合redis
- 12.springboot-整合jpa
- 13. springboot-整合定时任务
- 14.springboot-整合thymeleaf
- 15. springboot整合web组件
1. springboot简介
开发Maven项目[maven可以帮助我们进行项目的构建管理、快速的依赖第三方的jar包、对项目进行拆分开发]
Maven项目开发时,web类型的项目比较多,基本上大部分的mavenweb项目都需要使用框架,主流框架都是ssm,基本上所有的项目依赖的jar包都差不多。
Springboot项目可以基于maven项目进行依赖管理:
springboot创建了n多个 maven类型的项目,每个项目中都管理了一组依赖,范围时compile的,每个组都代表一个开发的场景,很多依赖都由springboot提供的默认配置。
我们在开发项目时,只需要引入springboot写好的maven项目的依赖,就可以拥有该场景对应的所有的依赖的jar包了。(依赖传递性)
springboot是框架之上的框架,就是通过maven的pom文件对依赖进行了分组管理
约定大于配置
springboot核心功能:1)起步依赖 2)自动配置
2. 本地maven方式创建springboot项目
项目需求:浏览器访问当前项目/hello,返回一个hello字符串
1.先创建java maven项目
2.修改项目的pom文件
2.1 需要继承springboot项目的父工程
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
</parent>
2.2 依赖当前场景需要的springboot的场景启动器
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
2.3 手动创建部署当前项目到web场景启动器携带的tomcat中并运行tomcat的主程序
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication //表示当前类为springboot的主程序
public class HelloWordofflineApplication {
//程序入口:Tomact的程序入口也是main方法。Java程序基本都是
public static void main(String[] args) {
SpringApplication.run(HelloWordofflineApplication.class,args);
}
}
2.4 在主程序所在的包或子包下创建处理用户请求的Controller
package com.atgui.springboot.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
//@Controller
@RestController//相当于当前Controller上标注了@Controller注解+每个方法上标注了@ResponseBody
public class HelloController {
@RequestMapping("/hello")
public String hello(){
return "hello-----------";
}
}
3. springboot场景启动器原理
场景启动器:一个场景启动器对应一个maven工程。该maven工程将当前 场景需要的依赖都已经在自己的pom中依赖好了
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.2.2.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
<version>2.2.2.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.2.2.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>2.2.2.RELEASE</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>tomcat-embed-el</artifactId>
<groupId>org.apache.tomcat.embed</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.2.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.2.RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
4. 联网创建springboot项目
1、创建springboot项目:https://start.aliyun.com
2、选择要使用的依赖:spring-web
注意:
联网创建的pom文件中的***相当于本地的
项目打包运行:
springboot提供了打包插件,使用时可以将springboot项目内置的tomcat一起打包
打成的jar包可以通过:java -jar jar包名称 直接运行访问
将连网的pom文件中涉及打包的部分复制到本地创建的项目的pom文件中
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<!-- <configuration>-->
<!-- <mainClass>com.atguigu.springboot.SpringbootHelloworldOnlineApplication</mainClass>-->
<!-- </configuration>-->
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
主要是下面这部分:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.0.RELEASE</version>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
5. springboot启动+自动配置原理
5.1 springboot场景启动器
对maven依赖的封装[创建一个maven项目将一组依赖添加到pom文件中]
5.2 springboot项目依赖的jar包的版本管理
springboot项目创建时会继承spring-boot-starter-parent工程
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
</parent>
spring-boot-starter-parent项目又继承了:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
spring-boot-dependencies项目中:
管理了springboot项目需要用到jar包的所有的版本
还通过dependencymanagement管理了多个依赖
如果自己的项目继承了spring-boot-starter-parent,就可以直接声明spring-boot-dependencies中依赖管理的jar包进行使用,无需执行版本
5.3 项目自动配置如何实现的
springboot项目初始化启动时,所有的默认配置和组件对象的扫描创建注入到容器中都是由主程序的注解来完成的
@SpringBootApplication
@Target(ElementType.TYPE) //当前注解可以标注的地方
@Retention(RetentionPolicy.RUNTIME) //当前注解起作用的时机
@Documented //文档
@Inherited //当前注解是否可以被继承
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
}
@SpringBootConfiguration //作用和Configuration一样,也是表示当前类是一个配置组件类
@ComponentScan //组件扫描 ,默认配置可以在主程序所在包及它的子包下扫描所有的组件类并创建对象注入到容器中
@EnableAutoConfiguration //启用自动配置的注解
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class) //AutoConfigurationImportSelector 自动配置的导入选择器
public @interface EnableAutoConfiguration {
}
AutoConfigurationImportSelector
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,
annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
AnnotationAttributes attributes = getAttributes(annotationMetadata);
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
configurations = removeDuplicates(configurations);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = filter(configurations, autoConfigurationMetadata);
fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}
getCandidateConfigurations:
此方法中会在项目的类路径下扫描META-INF目录下的spring.properties文件
spring.properties文件中描述了当前spring场景启动器需要使用的配置类全类名[配置对象可以自动加载springboot的默认配置还可以自动读取application.properties中的配置参数使用],配置类也通过@Configuration注解标注,会被容器创建对象,但是一般配置类会标注约束[在特定情况下才会被创建对象]。有些配置类中也会对配置类对应的场景需要使用的模板类对象进行初始化。
配置对象会根据依赖的场景启动器挑选需要初始化的配置对象进行使用
springboot-autoconfigure 包:自动配置包
6. springboot-配置文件
springboot项目创建时默认会在resources下提供application.properties文件,可以编写自定义配置
有些情况会存在默认配置[上边的自动配置]
6.1 application.properties
语法和我们以前的properties文件语法一样
server.port=10001
server.servlet.context-path=/app
6.2 application-后缀.yml
yml文件可以对应每个实际环境编写一个,然后在全局配置文件application.properties中选择激活哪一个环境的yml配置
yml文件和properties文件中如果存在相同的配置,优先使用properties文件中的
yml文件的语法:
属性和他的子属性需要换行,子属性使用空格(推荐两个空格)表示层级关系,属性和属性以及 属性和值之间都需要使用:分割 , 属性和值之间还需要有一个空格
yml文件会对配置进行自动归组
项目启动时默认会读取application名称的yml和application配置文件。
server:
port: 9002
servlet:
context-path: /myappdebug
session:
timeout: 30m
spring:
application:
name: app
如果希望对应环境的配置文件起作用,可以在application.properties选择要激活的yml文件
7. springboot-ssm整合
需求:查询数据库t_admin表中的所有的数据的json显示到页面中
1. 创建springboot项目,引入依赖
处理浏览器请求,引入springweb
操作数据库,引入jdbcAPI依赖
要使用mysql数据库,引入mysql的驱动
使用mybatis的依赖操作数据库+中间包
2. 使用mbg逆向工程逆向生成javabean+mapper文件
2.1 在项目中引入逆向工程的jar包+maven插件
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.7</version>
</dependency>
<build>
<!-- mbg mvn插件:可以通过mvn执行 mybatis逆向工程的命令 -->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.7</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.42</version>
</dependency>
</dependencies>
</plugin>
</build>
2.2 准备逆向工程的配置文件到项目的resources目录下
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="MySQLTables" targetRuntime="MyBatis3">
<commentGenerator>
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!-- mvn mybatis-generator:generate 配置数据库位置 ,配置虚拟机上的mysql ip地址;不采用安全协议连接,否则无法逆向生成 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/scw?useSSL=false"
userId="root" password="root">
</jdbcConnection>
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- javaBean生成在哪里 -->
<javaModelGenerator
targetPackage="com.atguigu.ssm.bean"
targetProject=".\src\main\java">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- sqlMap sql映射文件(xml mapper文件) -->
<sqlMapGenerator targetPackage="mybatis.mapper"
targetProject=".\src\main\resources">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!-- javaClient:java接口生成的地方 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.atguigu.ssm.mapper"
targetProject=".\src\main\java">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<table schema="" tableName="%"></table>
<!-- <table schema="TPermission" tableName="t_permission"></table> -->
</context>
</generatorConfiguration>
2.3 执行逆向工程
3. 完成Controller处理用户的请求
@RestController
public class AdminController {
@Autowired
AdminService adminService;
// @GetMapping 相当于@RequestMapping( method=RequestMethod.GET)
// @PostMapping
// @PutMapping
// @DeleteMapping
@GetMapping("/admins")
public List<TAdmin> getAllAdmins(){
return adminService.getAllAdmins();
}
}
service:
@Service
public class AdminServiceImpl implements AdminService {
@Autowired
TAdminMapper adminMapper;
@Override
public List<TAdmin> getAllAdmins() {
return adminMapper.selectByExample(null);
}
}
4. 准备mybatis的全局配置文件
在reousrce下创建 mybatis-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
</configuration>
5. 创建application.yml文件编写配置
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/scw?useSSL=false&useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.jdbc.Driver
mybatis:
# mybatis 所有mapper映射文件的路径
mapper-locations: classpath:mybatis/mapper/*.xml
# mybatis全局配置文件的路径
config-location: classpath:mybatis-config.xml
6. 告诉springboot项目的主程序扫描mapper接口包并创建组件对象
@SpringBootApplication
//指定mapper接口(组件)所在的包 :必须写到mapper接口所在的包
@MapperScan(basePackages = "com.atguigu.ssm.mapper" )
public class SpringbootSsmApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootSsmApplication.class, args);
}
}
8. springboot-ssm 整合druid
1. springboot项目默认自带的数据库连接池
数据库连接池的类名:com.zaxxer.hikari.HikariDataSource
HikariDataSource:性能非常高、但是没有后台监控系统
2. druid连接池
性能适中,自带后台管理系统可以监控sql的执行情况
以后开发中优先使用druid
2.1 引入Druid依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.23</version>
</dependency>
2.2 指定springboot创建连接池使用Druid
方式1: 在application.yml中指定:
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/scw?useSSL=false&useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.jdbc.Driver
# 指定创建druid连接池
type: com.alibaba.druid.pool.DruidDataSource
方式2: 通过@Bean的方式初始化druid数据库连接池对象
//在组件类中通过@Bean标注的方法的返回值也会被注入到容器中
@Bean
@ConfigurationProperties(prefix = "spring.datasource") //此注解可以根据指定的前缀加载配置文件中的属性,前缀后的属性名如果和返回的对象的属性名一样则自动将属性值设置给该属性
public DataSource getDruidDataSource(){
DruidDataSource dataSource = new DruidDataSource();
//设置数据库连接参数
return dataSource;
}
注意这里import javax.sql.DataSource; 不要错了。
2.3 druid的后台监控功能
在主程序中配置:
@Bean
@ConfigurationProperties(prefix = "spring.datasource") //此注解可以根据指定的前缀加载配置文件中的属性,前缀后的属性名如果和返回的对象的属性名一样则自动将属性值设置给该属性
public DataSource getDruidDataSource(){
DruidDataSource dataSource = new DruidDataSource();
try {
//启用druid连接池的监控的filter
dataSource.setFilters("stat, wall");
} catch (SQLException e) {
e.printStackTrace();
}
//设置数据库连接参数
return dataSource;
}
//配置Druid的监控
//1、配置一个管理后台的Servlet
@Bean
public ServletRegistrationBean statViewServlet() {
ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
Map<String, String> initParams = new HashMap<>();
initParams.put("loginUsername", "admin");
initParams.put("loginPassword", "123456");
initParams.put("allow", "");// 默认就是允许所有访问
initParams.put("deny", "192.168.15.21");
bean.setInitParameters(initParams);
return bean;
}
//2、配置一个web监控的filter
@Bean
public FilterRegistrationBean webStatFilter() {
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new WebStatFilter());
Map<String, String> initParams = new HashMap<>();
initParams.put("exclusions", "*.js,*.css,/druid/*");
bean.setInitParameters(initParams);
bean.setUrlPatterns(Arrays.asList("/*"));
return bean;
}
在浏览器中访问:http://localhost:端口号/druid/xx 可以访问druid的后台监控系统
9.springboot-单元测试的使用
如果springboot项目中引入的是junit4,单元测试类:
@SpringBootTest //可以使用spring容器
@RunWith(SpringRunner.class)
public class SpringbootSsmApplicationTests {
@Autowired
AdminService adminService;
@Test
public void contextLoads() {
System.out.println("adminService.getAllAdmins() = " + adminService.getAllAdmins());
}
}
如果springboot项目引入的是junit5依赖,单元测试类:
@SpringBootTest
class SpringbootSsmApplicationTests {
@Autowired
AdminService adminService;
@Test
void contextLoads() {
System.out.println("adminService.getAllAdmins() = " + adminService.getAllAdmins());
}
}
10.springboot-整合事务
springboot就是基于maven进行开发的项目,简化maven项目的开发
在ssm整合的项目中只要配置了事务管理器,启用了声明式的事务,在业务层使用@Transactional注解就可以启用事务
启用事务
1、在主程序类名上添加EnableTransactionManagement 启用声明式事务管理功能
2、在业务层类名上添加@Transactional //使用事务管理
11.springboot-整合redis
12.springboot-整合jpa
h是全自动的ORM映射框架[sql语句不方便手动修改]
mybatis属于半自动的ORM映射框架[sql可以手动优化编写]
jpa和h一样都属于全自动ORM映射框架
1. 创建springboot项目
引入依赖:web 、 jpa 、 mysql
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
2. 添加配置文件
logging:
level:
com.atguigu: debug # 配置日志
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://127.0.0.1:3306/scw?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.jdbc.Driver
jpa:
database: mysql
show-sql: true
generate-ddl: true
hibernate:
ddl-auto: update
naming_strategy: org.hibernate.cfg.ImprovedNamingStrategy
server:
port: 8081
3. jpa支持可以在javabean中绑定它对应的表[通过它提供的注解]
package com.atguigu.jpa.bean;
import javax.persistence.*;
//Table 声明javabean和数据库的t_admin表是映射关系
@Entity
@Table(name = "t_admin")
public class User {
//@Id表示当前字段为主键
//@Column 表示字段和表属性的映射关系
@Column(name = "id")
@Id
//表示主键自增
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "loginacct")
private String loginacct;
@Column(name = "username")
private String username;
@Column(name = "userpswd")
private String userpassword;
@Column(name = "email")
private String email;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLoginacct() {
return loginacct;
}
public void setLoginacct(String loginacct) {
this.loginacct = loginacct;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUserpassword() {
return userpassword;
}
public void setUserpassword(String userpassword) {
this.userpassword = userpassword;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
4、创建UserDao提供操作User类对应表的增删改查的方法
public interface UserDao extends JpaRepository<User, Integer> {
}
5、创建业务层UserServiceImpl 使用UserDao处理增删改查的业务
@Service
public class UserServiceImpl implements UserService {
@Autowired
UserDao userDao;
@Override
public List<User> findUsers() {
return userDao.findAll();
}
@Override
public User findUserById(Integer id) {
return userDao.findById(id).get();
}
@Override
public void saveUser(User user) {
userDao.save(user);
}
@Override
public void updateUser(User user) {
userDao.save(user);//save方法:如果传入的user对象有id值代表更新
}
@Override
public void deleteUserById(Integer id) {
userDao.deleteById(id);
}
}
6、创建UserController处理用户请求
@RestController
public class UserController {
@Autowired
UserService userService;
@RequestMapping("/users")
public List<User> getAllUsers(){
return userService.findUsers();
}
@RequestMapping("/user")
public User getUser(Integer id){
return userService.findUserById(id);
}
}
13. springboot-整合定时任务
js:setTimeout()
1、在项目中引入依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.2.7.RELEASE</version>
</dependency>
2、在主程序类名上启用定时任务功能
@EnableScheduling : 让主程序启用定时任务功能
@SpringBootApplication
@EnableScheduling //让主程序启用定时任务功能
public class SpringbootZJpaApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootZJpaApplication.class, args);
}
}
3、在主程序所在的包或子包下创建定时任务组件类编写定时任务
@Component:定时任务类必须是组件类
@Scheduled(fixedDelay = 3000)
fixedDelay=3000:
上一次定时任务方法执行结束3秒后执行下一次定时任务
fixedRate = 3000:
如果定时任务的耗时小于fixedRate的值:两次定时任务执行开始的时间间隔为3秒;
如果定时任务的耗时大于fixedRate的值:两次定时任务执行开始的时间间隔为定时任务的耗时时间。
cron 表达式:
可以自定义定时任务执行的时间字符串
//定时任务类可以编写多个定时任务方法
//定时任务类必须是组件类
@Component
public class MyTask {
//每隔3000毫秒执行一次定时任务
/**
* fixedDelay=3000:
* 上一次定时任务方法执行结束3秒后执行下一次定时任务
* fixedRate = 3000:
* 如果定时任务的耗时小于fixedRate的值:两次定时任务执行开始的时间间隔为3秒,
* 如果定时任务的耗时大于fixedRate的值:两次定时任务执行开始的时间间隔为定时任务的耗时时间。
* cron 表达式:
* 可以自定义定时任务执行的时间字符串
*
*/
@Scheduled(cron = "0,5,10,30 */1 * * * *") //cron = "0,5,10,30 */1 * * * *" 每分钟的第0/5/10/30秒执行一次定时任务
public void task02(){
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("begin: "+ format.format(new Date()));
// try {
// Thread.sleep(5000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// System.out.println("end: "+ format.format(new Date()));
}
// @Scheduled(fixedDelay = 3000)
// public void task01(){
//
// SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//
// System.out.println("begin: "+ format.format(new Date()));
// try {
// Thread.sleep(4000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// System.out.println("end: "+ format.format(new Date()));
// }
}
14.springboot-整合thymeleaf
jsp缺点: 性能差(jsp页面本质是Servlet,用户访问时tomcat服务器通过jsp引擎对页面进行翻译再使用jdk对类进行编译,再使用jvm执行class文件),以后的开发中不再推荐使用jsp
使用HTML页面,html页面中不能写动态的java代码,html代码由浏览器负责解析。
html页面中整合第三方的引擎(jar包),在页面需要使用动态代码的标签内使用jar包提供的语法去动态生成页面内容。
当用户访问html页面时,服务器会使用第三方的引擎对页面内容进行解析[只解析使用了它语法的标签,其他的不会解析]
thymeleaf:springboot推荐使用的
14.1 创建springboot项目整合tymeleaf
14.2 通过thymeleaf转发到html页面
项目的页面都是不能直接访问的,需要通过controller转发过去
springboot项目提供了templates目录,专门用来写html页面的,页面不能被直接访问
static目录下用来存放静态资源,浏览器可以直接访问
1、先在resources/templates中创建html页面
2、在项目的application.yml文件中配置thymeleaf
#前缀
spring.thymeleaf.prefix=classpath:/templates/
# 后缀
spring.thymeleaf.suffix=.html
# 关闭缓存
spring.thymeleaf.cache=false
3、创建Controller提供转发到html页面的方法
@Controller
public class HelloController {
@RequestMapping("/hello")
public String hello(){
return "hello"; //thymeleaf提供的视图解析器会自动拼接前后缀查找页面转发过去
}
}
14.3 thymeleaf的语法
当springboot项目转发到thymeleaf的html页面时,如果html页面的html标签内声明了:
<html lang="en" xmlns:th="http://www.thymeleaf.org" >
springboot就会使用thymeleaf的jar包(thymeleaf的引擎)解析html页面
解析页面中thymeleaf语法的内容,动态生成页面[thymeleaf的语法一般是在开始标签的内部通过th:* 属性来编写的]
解析完毕得到一个html页面然后相应给浏览器
1.获取域中简单类型数据显示到页面上
controller方法中向域中设置属性值:
//1、域中存储数据页面中通过thymeleaf的语法获取显示
@RequestMapping("/testScope")
public String testScope(Model model , HttpSession session){
//向model中存入数据
model.addAttribute("reqKey1" , "reqVal");
model.addAttribute("reqKey2" , 123);
//向session中存入数据
session.setAttribute("sessionKey" , "sessionVal");
//向application域中存入数据
ServletContext application = session.getServletContext();
application.setAttribute("appKey" , "appVal");
return "hello-scope";
}
获取域中的简单类型的数据显示
thymeleaf推荐在标签中通过它提供的属性的方式去获取属性值显示到标签内部
th:text 表示获取数据显示到双标签的内部
${key} :默认从request域中获取属性值
${session.sessionKey}:获取session域中的数据
${application.appKey}:获取application域中的数据
th:text="${session.sessionKey}==null?_:${session.sessionKey}"
:获取session中的数据如果为空则 使用_不要使用空替换标签内的默认文本,如果数据不为空则使用获取到的数据替换双标签内部的文本。
th:text="'获取用户名:'+${admin.username}"
:字符串拼接,字面量需要使用引号,自己进行手动拼接
th:text="|获取用户名: ${admin.username},密码: ${admin.userpswd}|"
:使用管道符进行拼接,让thymeleaf自己完成拼接。
[[$(admin.id)]]
:不在标签内使用thymeleaf语法的方式,利用[[]]获取。
添加:
<html lang="en" xmlns:th="http://www.thymeleaf.org" >
<h3>获取域中简单类型的数据显示</h3>
<div>获取req域中的数据:<span th:text="${reqKey1}"></span></div>
<div>获取req域中的数据:<span th:text="${reqKey2}-20"></span></div>
<div>获取session域中的数据: <span th:text="${session.sessionKey}==null?_:${session.sessionKey}">默认数据</span></div>
<div>获取application域中的数据: <span th:text="${application.appKey}"></span></div>
<div>获取req域中的数据:<span th:text="${admin}"></span></div>
<div>获取req域中的数据:<span th:text="'获取用户名:'+${admin.username}"></span></div>
<div>获取req域中的数据:<span th:text="|获取用户名: ${admin.username},密码: ${admin.userpswd}|"></span></div>
<div>先锋的id为:[[$(admin.id)]]</div>
2.获取集合类型数据遍历显示到页面上
1、在域中存储集和类型的数据
//2、域中存储集合类型数据在thymeleaf的页面中遍历显示到表格中
@RequestMapping("/testScope2")
public String testScope2(Model model){
ArrayList<TAdmin> list = new ArrayList<>();
list.add(new TAdmin(9527 , "fengge" , "123456" , "先锋" , "xx" , "xxx"));
list.add(new TAdmin(9528 , "fengjie" , "123456" , "先锋" , "xx" , "xxx"));
list.add(new TAdmin(9529 , "fengdi" , "123456" , "先锋" , "xx" , "xxx"));
list.add(new TAdmin(9530 , "fengmei" , "123456" , "先锋" , "xx" , "xxx"));
list.add(new TAdmin(9531 , "guoge" , "123456" , "先锋" , "xx" , "xxx"));
list.add(new TAdmin(9532 , "guodi" , "123456" , "先锋" , "xx" , "xxx"));
list.add(new TAdmin(9533 , "guojie" , "123456" , "先锋" , "xx" , "xxx"));
model.addAttribute("list",list);
HashMap<Integer, TAdmin> map = new HashMap<>();
map.put(9527 , new TAdmin(9527 , "fengge" , "123456" , "先锋" , "xx" , "xxx"));
map.put(9528 , new TAdmin(9528 , "fengjie" , "123456" , "先锋" , "xx" , "xxx"));
map.put(9529 , new TAdmin(9529 , "fengdi" , "123456" , "先锋" , "xx" , "xxx"));
model.addAttribute("map",map);
return "hello-collection";
}
2、在页面中使用th:each属性遍历集合
th:if=""
表示判断,如果条件成立,该属性所在的标签整体才会被创建。
th:if="${not #lists.isEmpty(list)}"
如果request域中的list长度不为0并且不为null则显示属性所在的标签。
#lists :thymeleaf
提供的处理集合的内置对象
isEmpty(list):
进行为空判断的方法,list代表从request域中获取list,如果从session中获取 isEmpty(session.list)
not
:表示取反
th:each=""
:表示遍历,每次遍历,所在的标签都会创建一次。
th:each="admin,vs:${list}"
类似于增强for循环,admin表示正在遍历的集合中的一个元素。
vs
表示正在遍历的状态对象,包括正在遍历的元素、遍历元素的索引,已经遍历了几个元素。
<!-- 1、先判断集合是否为空 -->
<table th:if="${not #lists.isEmpty(list)}" border="1" width="70%">
<tr>
<th>序号</th>
<th>id</th>
<th>用户名</th>
<th>账号</th>
<th>密码</th>
</tr>
<!-- 遍历集合,集合中的每个对象都对应一行显示 -->
<tr th:each="admin,vs:${list}">
<td th:text="${vs.count}"></td>
<td th:text="${admin.id}">1000</td>
<td th:text="${admin.username}==null?_:${admin.username}">未知</td>
<td th:text="${admin.loginacct}">游客</td>
<td th:text="${admin.userpswd}">*****</td>
</tr>
</table>
<!-- 2、遍历map 每次遍历map得到的是map的key和value组成的item对象 -->
<div th:each="item:${map}">
<span th:text="|正在遍历元素的key: ${item.key} , 正在遍历元素的value: ${item.value.username }|"></span>
</div>
3.动态设置标签属性值
th:attr :为了可以在html页面中动态的给标签的属性设置属性值
thymeleaf给标签的每个属性都提供了对应的th:属性名 替代方法
只要通过th:属性名就可以动态的去设置对应的属性值
<!-- 1、先判断集合是否为空 -->
<table th:if="${not #lists.isEmpty(list)}" border="1" width="70%">
<tr>
<th>序号</th>
<th>id</th>
<th>用户名</th>
<th>账号</th>
<th>密码</th>
<th>操作</th>
</tr>
<!-- 遍历集合,集合中的每个对象都对应一行显示 -->
<tr th:each="admin,vs:${list}">
<td th:text="${vs.count}"></td>
<td th:text="${admin.id}">1000</td>
<td th:text="${admin.username}==null?_:${admin.username}">未知</td>
<td th:text="${admin.loginacct}">游客</td>
<td th:text="${admin.userpswd}">*****</td>
<!--
th:attr :为了可以在html页面中动态的给标签的属性设置属性值
thymeleaf给标签的每个属性都提供了对应的th:属性名 替代方法
只要通过th:属性名就可以动态的去设置对应的属性值
-->
<td><span><a th:adminid="${admin.id}" th:href="|/admin/updateAdmin?id=${admin.id}|" href="/admin/updateAdmin?id=${admin.id}">修改</a></span> <span><a th:href="|/admin/delAdmin?id=${admin.id}|" href="/admin/delAdmin?id=${admin.id}">删除</a></span></td>
</tr>
</table>
4. thymeleaf的表达式
1. ~{}:在页面中静态包含提取的页面碎片
抽取的页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" >
<head>
<meta charset="UTF-8">
<title>碎片页面</title>
</head>
<body>
<div th:fragment="head_fragment">
<h1>这是页面的head</h1>
</div>
<div id="footer_fragement">
<h1>这是页面的footer</h1>
</div>
</body>
</html>
静态包含碎片的页面:
<!-- 如果页面碎片使用th:fragment设置的属性值,直接可以使用属性值引用页面 -->
<span th:include="~{include/base_fragement::head_fragment}"></span>
<!-- th:include=""
include/base_fragement :要使用的碎片所在的页面的视图名称,由thymeleaf的视图解析器拼接前后缀来查找
#footer_fragement :通过id选择器引用页面碎片
-->
<div th:include="~{include/base_fragement::#footer_fragement}"></div>
2. ${}: 获取域中的属性值
3. @{}:处理绝对路径
<a th:adminid="${admin.id}" th:href="@{|/admin/updateAdmin?id=${admin.id}|}" href="/admin/updateAdmin?id=${admin.id}">修改</a>
15. springboot整合web组件
servlet
listener
filter
1、创建项目引入web场景启动器
2、创建web组件
//使用注解将web组件注册到tomcat容器中
@WebServlet("/AServlet")
public class AServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
System.out.println("AServlet接受到请求。。。。。" );
resp.getWriter().write("AServlet的相应");
}
}
@WebListener
public class BListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("全局上下文对象创建成功了......." );
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("项目即将停止,全局上下文对象即将销毁......");
}
}
@WebFilter("/*")
public class CFilter extends HttpFilter {
@Override
protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("CFilter 拦截了本次请求......");
chain.doFilter(request,response);//放行
}
}
3、在主程序上启用注解扫描web组件
@SpringBootApplication //默认只会扫描spring的组件类并创建对象管理
@ServletComponentScan //让主程序扫描web组件并注册到web容器中
public class SpringbootZWebApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootZWebApplication.class, args);
}
}