SpringBoot优点
详细描述
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.1.9.RELEASEversion>
<relativePath/>
parent>
<groupId>com.kuanggroupId>
<artifactId>springboot-01-helloworldartifactId>
<version>0.0.1-SNAPSHOTversion>
<name>springboot-01-helloworldname>
<description>springboot-01-helloworlddescription>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<configuration>
<fork>truefork>
configuration>
plugin>
plugins>
build>
project>
如上所示,主要有四个部分:
spring-boot-starter-parent
的依赖管理,控制版本与打包等内容spring-boot-starter-web
用于实现HTTP接口(该依赖中包含了Spring MVC),官网对它的描述是:使用Spring MVC构建Web(包括RESTful)应用程序的入门者,使用Tomcat作为默认嵌入式容器。;spring-boot-starter-test
用于编写单元测试的依赖包。更多功能模块的使用我们将在后面逐步展开。spring-boot-maven-plugin
,配合spring-boot-starter-parent
就可以把Spring Boot应用打包成JAR来直接运行。更改项目端口号
基于java代码的bean配置
@Configuration&、@Bean这两个bean的注解一起使用就可以创建一个基于java代码的配置类,可以用来替代相应的xml配置文件
@Configuration注解的类可以看作是能生产让Spring IoC容器管理的Bean实例的工厂。
@Bean注解告诉Spring,一个带有@Bean的注解方法将返回一个对象,该对象应该被注册到spring容器中。
传统的基于xml的bean配置方法如下:
<beans>
property>
bean>
bean>
beans>
相当于用基于java代码的配置方式:
@Configuration
public class Conf {
@Bean
public Car car() {
Car car = new Car();
car.setWheel(wheel());
return car;
}
@Bean
public Wheel wheel() {
return new Wheel();
}
}
所以上面的MybatisAutoConfiguration这个类,自动帮我们生成了SqlSessionFactory这些Mybatis的重要实例并交给spring容器管理,从而完成bean的自动注册。
详细地址
自动配置:
启动器:
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starterartifactId>
dependency>
启动器:就是Springboot的启动场景
比如spring-boot-starter-web,他就会帮我们自动导入web环境所有的依赖!
springboot会将所有的功能场景,都变成一个个的启动器
我们要使用什么功能,就只需要找到对应的启动器就可以了
主程序:
//@SpringBootApplication 来标注一个主程序类,说明这是一个SpringBoot的应用
@SpringBootApplication
public class Springboot01HelloworldApplication {
public static void main(String[] args) {
//将SpringBoot应用启动 静态方法run
SpringApplication.run(Springboot01HelloworldApplication.class, args); }}
- @SpringBootConfiguration : springboot的配置
@Configuration : spring配置类
@Component : 说明这也是一个spring的组件
- @EnableAutoConfiguration : 自动配置
@AutoConfigurationPackage : 自动配置包
@Import(AutoConfigurationPackages.Registrar.class) : 自动配置包.包注册
@Import(AutoConfigurationImportSelector.class) : 自动配置导入选择器
//获取所有的配置 : List configurations = 获取候选的配置(元注解,属性)
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
META-INF/spring.factories : 自动配置的核心文件
结论:springboot所有自动配置都是在启动的时候扫描并加载:spring.factories(工厂)所有的自动配置类都在这里面,但是不一定都生效,要判断条件是否成立,只要导入了对应的start,就有对应的启动器了,有了启动器,我们自动装配就会生效,然后就配置成功!
/META-INF/spring.factories
获取指定的值spring-boot-autoconfigure-2.2.5.RELEASE.jar
这个包下run():
@Conditional派生注解 : 必须是@Conditional指定的条件成立,才给容器中添加组件,配置类里面的所有内容才生效
Springboot使用一个全局的配置文件,配置文件名称是固定的
配置文件的作用: 修改springboot自动配置的默认值.
详细地址
yaml可以给实体类赋值,也可以成为JavaConfiguration配置
但是不影响程序的运行
@ConfigurationProperties(prefix = “person”)
将配置文件中配置的每一个属性的值,映射到这个组件中
告诉springboot将本类中的所有属性和配置文件中相关的配置绑定,可以修改springboot属性的默认值
只有这个组件是容器中的组件,才能使用容器提供的@ConfigurationProperties功能
一但配置类生效,这个配置类就会给容器中添加各种组件,这些组件的属性是从对应的properties(属性)类中获取的,这些类里面的每一个属性又是和配置文件绑定的
占位符:
person:
name: ${random.uuid}
result: name='46df8e31-7c35-4873-9f09-52d46d5bbc71'
age: ${random.int}
result: age=1569119886
happy: true
birth: 2020/1/1
maps: {k1: v1, k2: v2}
lists:
- code
- music
- girl
dog:
name: ${person.happy}_旺财
age: 3
result: dog=Dog{name='true_旺财', age=3}
---
server:
port: 8081
spring:
profiles:
active: dev 激活dev端口 修改springboot默认值
--- 分割线
server:
port: 8082
spring:
profiles: dev
详细地址
@Validated : 在类上开启数据校验
在springboot中,我们可以使用以下方式请求静态资源
localhost:8080/webjars/
localhost:8080/
优先级: resources > static(默认) > public (同样的js文件,在不同层级文件夹的访问优先度)
前端交给我们的页面,是html页面,以前开发需要把html转成jsp页面,因为可以绑定后台数据输出, jsp也是个模板引擎,
springboot推荐使用thymeleaf,不推荐jsp
与其它模板引擎相比,Thymeleaf 最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个 Web 应用。
只要需要使用thymeleaf(塞姆莉夫),导入对应的依赖就可以,将html放在templates目录下即可
在html页面取出一个简单的值:
<h1 th:text="${msg}">h1>
//部门dao
@Repository
public class DepartmentDao {
private static Map<Integer, Department>departments = null;
static {
departments = new HashMap<Integer, Department>();//创建一个部门表
departments.put(101,new Department(101,"教学部"));
departments.put(102,new Department(102,"市场部"));
departments.put(103,new Department(103,"调研部"));
departments.put(104,new Department(104,"后勤部"));
departments.put(105,new Department(105,"研发部"));
}
//获取所有部门信息
public Collection<Department> getDepartments(){
return departments.values();
}
//通过id的到部门
public Department getDepartmentById(Integer id){
return departments.get(id);
}
//员工dao
@Repository
public class EmployeeDao {
//模拟数据库中的数据
private static Map<Integer, Employee> employees = null;
//员工有所属部门
@Autowired
private DepartmentDao departmentDao;
static {
employees = new HashMap<Integer, Employee>();//创建一个部门表
employees.put(1001,new Employee(1001,"AA","[email protected]",0,new Department(101,"教学部")));
employees.put(1002,new Employee(1002,"BB","[email protected]",1,new Department(102,"市场部")));
employees.put(1003,new Employee(1003,"CC","[email protected]",0,new Department(103,"调研部")));
employees.put(1004,new Employee(1004,"DD","[email protected]",1,new Department(104,"后勤部")));
employees.put(1005,new Employee(1005,"EE","[email protected]",0,new Department(105,"研发部")));
}
//主键自增
private static Integer initId = 1006;
//增加一个员工
public void save(Employee employee){
if (employee.getId()==null){
employee.setId(initId++);
}
employee.setDepartment(departmentDao.getDepartmentById(employee.getDepartment().getId()));
employees.put(employee.getId(),employee);
}
//查询全部员工信息
public Collection<Employee> getAll(){
return employees.values();
}
//通过id查询员工
public Employee getEmployeeById(Integer id){
return employees.get(id);
}
//删除员工
public void delete(Integer id){
employees.remove(id);
}}
首页配置:
3. 路径如果乱码修改File Encodings默认编码格式为UTF-8
4. url使用@{},参数使用#{}
# 关闭模板引擎缓存
spring:
thymeleaf:
cache: false
#
# [[#{login.Remember}]]
#
messages:
basename: i18n.login
#时间日期格式化
mvc:
date-format: yyyy-MM-dd
#更改访问路径 http://localhost:8080/zjt/
server:
servlet:
context-path: /zjt
<a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">中文a>
<a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">Englisha>
public class MyLocaleResolver implements LocaleResolver {
//解析请求
@Override
public Locale resolveLocale(HttpServletRequest request) {
//获取请求中的语言参数
String language = request.getParameter("l");
//如果没有就使用默认的
Locale locale = Locale.getDefault();
//如果请求的链接携带了国际化参数
if (! StringUtils.isEmpty(language)){
//zh_CN
String[] split = language.split("_");
/国家,地区
locale = new Locale(split[0], split[1]);
}
return locale;
}
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override //重写默认跳转地址
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
}
//自定义国际化组件生效
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
}
登录控制层
@Controller
public class LoginController {
@RequestMapping("/user/login")
public String login(
@RequestParam("username")String username,
@RequestParam("password")String password,
Model model, HttpSession session){
if (!StringUtils.isEmpty(username)&&"1".equals(password)){
session.setAttribute("loginUser",username);
return "redirect:/main.html";
}else{
model.addAttribute("msg","用户名和密码错误");
return "index";
}
}
//退出登录
@RequestMapping("/user/logout")
public String loginout(HttpSession session){
session.invalidate();//让session失效
return "redirect:/index.html";
}
}
自定义拦截器
public class LoginHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//登陆成功之后应该有用户的session
Object loginUser = request.getSession().getAttribute("loginUser");
if (loginUser == null) {
request.setAttribute("msg", "没有登陆,请先登录");
request.getRequestDispatcher("/index.html").forward(request, response);
return false;
} else {
return true;
}
}
}
自定义WebMvcConfigurer,使拦截器生效
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
registry.addViewController("/main.html").setViewName("dashboard");
}
//让拦截器生效注册到webmvc配置
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHandlerInterceptor())
.addPathPatterns("/**")//拦截全部
.excludePathPatterns("/css/**","/js/**","/img/**","/","/index.html","/user/login");//忽略的请求
}
}
thymeleaf模板页面接值
<p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}">p>
提取公共页面
<thead>
<tr>
<th>idth>
<th>lastNameth>
<th>emailth>
<th>genderth>
<th>departmentth>
<th>birthth>
<th>操作th>
tr>
thead>
<tbody>
<tr th:each="emp:${emps}">
<td th:text="${emp.getId()}">td>
<td th:text="${emp.getLastName()}">td>
<td th:text="${emp.getEmail()}">td>
<td th:text="${emp.getGender()==0 ? '女' : '男'}">td>
<td th:text="${emp.department.getDepartmentName()}">td>
<td th:text="${#dates.format(emp.getBirth(),'yyyy-MM-dd HH:mm:ss' )}">td>
<td>
<button class="btn btn-sm btn-primary">编辑button>
<button class="btn btn-sm btn-danger">删除button>
td>
tr>
tbody>
Druid是一个JDBC组件库,包括数据库连接池、SQL Parser等组件。
DruidDataSource是最好的数据库连接池。
Druid能够提供强大的监控和扩展功能。
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.1.10version>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.17version>
dependency>
spring:
datasource:
username: root
password: root
url: jdbc:mysql://localhost:3306/ssmbuild?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
# 初始化连接池个数
initialSize: 5
# 最小连接池个数——》已经不再使用,配置了也没效果
minIdle: 2
# 最大连接池个数
maxActive: 20
# 配置获取连接等待超时的时间,单位毫秒,缺省启用公平锁,并发效率会有所下降
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
# 用来检测连接是否有效的sql,要求是一个查询语句。
# 如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用
validationQuery: SELECT 1 FROM DUAL
# 建议配置为true,不影响性能,并且保证安全性。
# 申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
testWhileIdle: true
# 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
testOnBorrow: false
# 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
testOnReturn: false
# 打开PSCache,并且指定每个连接上PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
# 通过别名的方式配置扩展插件,多个英文逗号分隔,常用的插件有:
# 监控统计用的filter:stat
# 日志用的filter:log4j
# 防御sql注入的filter:wall
filters: stat,wall,log4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
# 合并多个DruidDataSource的监控数据
useGlobalDataSourceStat: true
@Configuration
public class DruidConfig {
@Bean//对应application.yml的连库和Druid德鲁伊 配置
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource druidDataSource(){
return new DruidDataSource();
}
//后台监控 : 后台:http://localhost:8080/druid/index.html
//因为springboot内置了servlet容器,所以没有web.xml,用ServletRegistrationBean替代
@Bean
public ServletRegistrationBean statViewServlet(){
ServletRegistrationBean<StatViewServlet> servletBean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
//后台需要有人登陆,账号密码设置
HashMap<String, String> initParameters = new HashMap<>();
//控制台管理用户名 参数固定的 loginUsername loginPassword
initParameters.put("loginUsername","admin");
initParameters.put("loginPassword","1");
//白名单,多个用逗号分割, 如果allow没有配置或者为空,则允许所有访问
initParameters.put("allow","");
servletBean.setInitParameters(initParameters);//初始化参数
return servletBean;
}
//filtel
@Bean
public FilterRegistrationBean webStatFilter(){
FilterRegistrationBean filterBean = new FilterRegistrationBean();
filterBean.setFilter(new WebStatFilter());
//可以过滤的请求
HashMap<String, String> initParameters = new HashMap<>();
//这些东西不进行统计
initParameters.put("exclusions","*.js,*.css,/druid/*");
filterBean.setInitParameters(initParameters);
return filterBean;
}
}
spring:
datasource:
username: root
password: root
url: jdbc:mysql://localhost:3306/ssmbuild?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
type-aliases-package: com.zjt.pojo
mapper-locations: classpath:mybatis/mapper/*.xml
@SpringBootApplication.
//重要注解 扫描包下的mapper接口,或者用@Mapper在类上代替
@MapperScan("com.zjt.mapper")
public class Springboot05MybatisApplication {
public static void main(String[] args) {
SpringApplication.run(Springboot05MybatisApplication.class, args);
}
}
<mapper namespace="com.zjt.mapper.UserMapper">