概述
springboot与spring、springmvc
- 由于spring、springmvc需要使用大量的xml配置文件 因此使用起来比较麻烦
- 而springboot就相当于是不需要使用xml配置文件的spring、springmvc 简化了使用 开发效率较高
- 且springboot还提供了起步依赖starter、还有自动配置(即尽可能多的去配置常用框架与第三方库并放到spring容器中 使得开发人员可以直接使用)、还内嵌了tomcat、jetty等
springboot项目的创建
https://start.spring.io
而后选择依赖即可
但此为访问外网创建的springboot项目 即在下载依赖时有可能会timeout
https://start.springboot.io
- 仅将Server URL(初始化器地址)修改为https://start.springboot.io即可
- 此为访问国内的地址来创建的springboot项目
maven项目转springboot项目
- 创建maven项目后手动创建static目录(静态资源文件目录)、templates目录(模板文件目录)、application.properties文件/application.yml文件(springboot的核心配置文件)、Application类(入口类) 以及手动修改pom文件
导入项目
- 在浏览器中打开https://start.spring.io或https://start.springboot.io并填写信息
- 按GENERATE以生成项目 然后在idea中导入项目即可
- 按EXPLORE以查看即将生成的项目中的各种文件以copy所需要的代码
@SpringBootApplication
-
是Application入口类的类注解
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
-
是一个复合注解 由@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan等注解组成
@SpringBootConfiguration
-
其实就是@Configuration
@Configuration @Indexed public @interface SpringBootConfiguration { @AliasFor( annotation = Configuration.class ) boolean proxyBeanMethods() default true; }
-
被注解的类将作为配置文件来使用
@EnableAutoConfiguration
- 即启动自动配置 即被注解的类其中的对象会自动被配置好并注入到spring容器中
@ComponentScan
- 组件扫描器
- 扫描注解并根据注解的功能创建对象与给属性赋值等
- 默认扫描的范围为本类、本类所在的包及其子包
JavaConfig
- 即使用java类来代替xml配置文件
- 优点
- 避免了繁琐的xml配置
- 使用面向对象的方式来创建对象并将对象放入spring容器中
- 一个配置类可以继承另一个配置类
@Configuration与@Bean
//表示此类会被当作xml配置文件来使用
@Configuration
public class SpringConfig {
//表示此方法的返回值即对象会被自动注入到spring容器中
//不指定name的话 则方法名即为此对象在spring容器中的id
//@Bean
@Bean(name = "zhangsanStudent")
public Student createStudent() {
return new Student("zhangsan", 26);
}
}
@ImportResource
@Configuration
//表示自动导入xml配置文件
@ImportResource(value = {
"classpath:beans.xml", "classpath:applicationContext.xml"})
public class SpringConfig {
}
@PropertySource
@Configuration
//表示自动读取properties属性配置文件
@PropertySource(value = {
"classpath:beans.properties", "classpath:test.properties"})
public class SpringConfig {
//使用@Value注解并使用properties属性配置文件中的参数给变量赋值
@Value("${student.name}")
private String studentName;
}
@Value
@Configuration
@PropertySource(value = "classpath:beans.properties")
public class SpringConfig {
//用来给单一属性赋值
//使用@Value注解给属性赋值
//@Value("张三")
//使用@Value注解并使用properties属性配置文件中的参数给属性赋值
@Value("${student.name}")
private String studentName;
}
@ConfigurationProperties
@Component
//用来给多个属性赋值
//若无prefix 虽爆红但仍可运行 表示查找application.properties/yml文件中的name、add、sex属性(找不到则赋值为null)
//@ConfigurationProperties
//若有prefix 表示查找application.properties/yml文件中的student.name、student.add、student.sex属性(找不到则赋值为null)
@ConfigurationProperties(prefix = "student")
public class Student {
private String name;
private String add;
private String sex;
//必须得有setter以给属性赋值
}
//写controller并在入口类中运行才行 不能使用junit测试
@Controller
public class MyController {
@Resource
private Student student;
@RequestMapping("/mystudent")
@ResponseBody
public String getStudent() {
return student.toString();
}
}
<!-- 当使用了@ConfigurationProperties注解时idea会弹出一个警告 安装此依赖即可解决此问题 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
@ComponentScan
@Configuration
@PropertySource(value = {
"classpath:beans.properties"})
//扫描注解并根据注解的功能创建对象与给属性赋值等
@ComponentScan(basePackages = {
"com.vo"})
public class SpringConfig {
}
//表示创建一个School对象并将此对象注入到spring容器中且id为school
@Component("school")
public class School {
//使用@Value注解并使用properties属性配置文件中的参数给变量赋值
@Value("${school.name}")
private String name;
@Value("${school.add}")
private String add;
}
springboot的核心配置文件
- 文件名称为application/以application开头
- 文件扩展名为properties(默认)/yml(推荐)
- yml是一种yaml格式的配置文件 主要采用换行、空格、冒号等进行排版
- .yml也可以写成.yaml
- 注意 值与冒号之间一定得有一个空格
- 优点
- 直观
- 简洁
- 默认优先使用的是properties格式的配置文件 若找不到才找yml格式的配置文件 建议不要同时存在这两个文件
application.properties
#设置端口号
server.port=8081
#设置contextpath
server.servlet.context-path=/myspringboot
application.yml
server:
#设置端口号
port: 8082
servlet:
#设置contextpath
context-path: /myspringboot2
多环境配置
- 在实际开发中 项目会经历开发、测试、上线阶段 而每个阶段的配置是不同的 而为了方便在不同的环境之间切换 springboot提供了多环境配置
- 创建开发环境(application-dev.yml)、测试环境(application-test.yml)、生产环境(application-product/online.yml)的配置文件并在application.yml核心配置文件中的spring.profiles.active属性中指定所使用的环境配置文件(dev/test/product)
在springboot中使用jsp
- 实际上springboot并不推荐使用jsp 而是使用模板(如thymeleaf)来代替jsp
添加依赖
<!-- 若仅使用jsp页面 则可以只添加此依赖 此依赖负责编译jsp文件 -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<!-- 若要使用servlet 则得添加以下依赖 -->
<!-- 注意 servlet与jsp依赖的scope得设为provided 因为在编译时的request与response对象是由这些依赖提供的 而在运行时 这些对象由tomcat提供 因此若不设为provided 则在运行时会与tomcat的对象冲突 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- 此依赖得指定version 否则会报错 -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
<!-- 若要使用jstl标签 则得添加此依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
配置resource
<!-- springboot要求jsp文件必须编译到指定的目录下即META-INF/resources目录才能访问 -->
<resources>
<resource>
<!-- jsp文件的原来的目录 -->
<!-- jsp文件一般存放到main目录下的webapp目录 -->
<directory>src/main/webapp</directory>
<!-- 编译后的存放目录 -->
<targetPath>META-INF/resources</targetPath>
<!-- 要进行处理的目录与文件 -->
<!-- **表示webapp目录及其子目录 *.*表示所有文件 -->
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
配置application.yml
server:
servlet:
context-path: /springboot
#配置视图解析器
spring:
mvc:
view:
#/相当于src/main/webapp/
prefix: /
suffix: .jsp
编写controller
@Controller
public class SpringBootController {
@RequestMapping(value = "/jsp")
public String jsp(Model model) {
model.addAttribute("msg", "在springboot中使用jsp");
return "index";
}
}
编写index.jsp
<!-- webapp目录不能新建出jsp文件是因为没有设置webapp目录为WebResourceDirectory 在ProjectStructure的Facets的Web中设置 -->
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%
//http://127.0.0.1:80/ssm/XXX.do
String basePath = request.getScheme() + "://" + request.getServerName()
+ ":" + request.getServerPort() + request.getContextPath() + "/";
%>
<html>
<head>
<title>index</title>
<base href="<%=basePath%>">
</head>
<body>
${msg}
</body>
</html>
运行入口类
springboot的spring容器对象
ConfigurableApplicationContext与ApplicationContext
public interface HelloService {
String sayHello(String username);
}
@Service
public class HelloServiceImpl implements HelloService {
@Override
public String sayHello(String username) {
return "你好 -> " + username;
}
}
@SpringBootApplication
public class Application {
public static void main(String[] args) {
//获取spring容器对象ConfigurableApplicationContext/ApplicationContext
//ConfigurableApplicationContext ctx = SpringApplication.run(Application.class, args);
ApplicationContext ctx = SpringApplication.run(Application.class, args);
//从spring容器中获取对象
HelloService service = (HelloService) ctx.getBean("helloServiceImpl");
//调用方法
System.out.println(service.sayHello("张三"));
}
}
源码
//SpringApplication.run(Application.class, args)
public class SpringApplication {
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
return run(new Class[]{
primarySource}, args);
}
}
//ConfigurableApplicationContext接口是ApplicationContext接口的子接口
public interface ConfigurableApplicationContext extends ApplicationContext {
}
CommandLineRunner与ApplicationRunner
-
当入口类实现这两个接口并重写run()后会在spring容器对象创建好后立刻执行run()而不执行SpringApplication.run(Application.class, args)后面的代码
-
这两个接口的区别为run()参数的不同
-
CommandLineRunner的参数为
@Override public void run(String... args) throws Exception { }
-
ApplicationRunner的参数为
@Override public void run(ApplicationArguments args) throws Exception { }
-
@SpringBootApplication
public class Application implements CommandLineRunner {
public static void main(String[] args) {
//获取spring容器对象
//ConfigurableApplicationContext ctx = SpringApplication.run(Application.class, args);
ApplicationContext ctx = SpringApplication.run(Application.class, args);
//从spring容器中获取对象
HelloService service = (HelloService) ctx.getBean("helloServiceImpl");
//调用方法
System.out.println(service.sayHello("张三"));
}
@Override
public void run(String... args) throws Exception {
System.out.println("spring容器对象创建好后立刻执行的方法");
}
}
/*
输出:
spring容器对象创建好后立刻执行的方法
你好 -> 张三
*/
web组件
interceptor
创建拦截器并实现HandlerInterceptor接口
public class LoginInterceptor implements HandlerInterceptor {
//各参数与返回值所表达的含义与springmvc中的一致
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("执行preHandle()");
return true;
}
}
创建javaconfig并实现WebMvcConfigurer接口
@Configuration
public class MyConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
//创建拦截器对象
HandlerInterceptor interceptor = new LoginInterceptor();
//指定拦截器所拦截的地址
String[] path = {
"/user/**"};
//指定拦截器所不拦截的地址
String[] excludePath = {
"/user/login"};
registry.addInterceptor(interceptor)
.addPathPatterns(path)
.excludePathPatterns(excludePath);
}
}
创建controller以进行测试
@Controller
public class MyController {
@RequestMapping("/user/login")
@ResponseBody
public String userLogin() {
return "执行userLogin()";
}
@RequestMapping("/user/query")
@ResponseBody
public String userQuery() {
return "执行userQuery()";
}
}
servlet
创建servlet并继承HttpServlet抽象类
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.println("执行servlet");
out.flush();
out.close();
}
}
创建javaconfig以进行测试
@Configuration
public class MyConfig {
@Bean
public ServletRegistrationBean servletRegistrationBean() {
//第一个参数为servlet对象 第二个参数为此servlet的别名即url-pattern
ServletRegistrationBean bean = new ServletRegistrationBean();
bean.setServlet(new MyServlet());
bean.addUrlMappings("/myservlet");
return bean;
}
}
filter
创建filter并实现Filter接口
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("执行了doFilter()");
filterChain.doFilter(servletRequest, servletResponse);
}
}
创建javaconfig
@Configuration
public class MyConfig {
@Bean
public FilterRegistrationBean filterRegistrationBean() {
//第一个参数为filter对象 第二个参数为此filter所要过滤的地址即url-pattern
FilterRegistrationBean<Filter> bean = new FilterRegistrationBean<>();
bean.setFilter(new MyFilter());
bean.addUrlPatterns("/user/*");
return bean;
}
}
创建controller以进行测试
@Controller
public class MyController {
@RequestMapping("/user/query")
@ResponseBody
public String userQuery() {
System.out.println("执行userQuery()");
return "";
}
@RequestMapping("/query")
@ResponseBody
public String query() {
System.out.println("执行query()");
return "";
}
}
character encoding filter
自定义CharacterEncodingFilter
创建servlet
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.println("执行servlet");
out.flush();
out.close();
}
}
创建javaconfig
@Configuration
public class MyConfig {
//注册servlet
@Bean
public ServletRegistrationBean servletRegistrationBean() {
ServletRegistrationBean srb = new ServletRegistrationBean(new MyServlet(), "/myservlet");
return srb;
}
//注册filter
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean frb = new FilterRegistrationBean();
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("utf-8");
filter.setForceEncoding(true);
frb.setFilter(filter);
frb.addUrlPatterns("/*");
return frb;
}
}
修改application.yml文件并进行测试
#因为springboot中默认已配置好了CharacterEncodingFilter且默认为ISO-8859-1
#因此要关闭springboot中已经配置好了的过滤器以使用自定义的CharacterEncodingFilter
server:
servlet:
encoding:
enabled: false
修改springboot所提供的CharacterEncodingFilter
修改application.yml文件并进行测试
#因为springboot中已经有了CharacterEncodingFilter 因此配置它的参数即可
server:
servlet:
encoding:
enabled: true
charset: UTF-8
force: true
springboot集成mybatis
集成步骤
添加依赖
<!-- mybatis依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<!-- mysql依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
配置resource
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes