主线5:SpringBoot

197 阅读12分钟

springboot框架

一.springboot简介

1.JavaConfig

概念

使用java类作为xml配置文件的替代,是配置spring的纯java方式。在这个java类可以创建java对象,把对象放入spring容器中(注入容器)。

相关注解

1).@Configuration:放在一个类的上面,表示该类作为配置文件使用的。

栗子:

@Configuration
public class 配置文件名 {}

相当于:beans.xml文件

2).@Bean:用来声明对象注入到容器中。

​ 方法的返回值是对象,在方法的上面加入@Bean,方法返回值将注入到容器中。

栗子:

@Configuration
public class SpringConfig{
    @Bean("student")
    public Student createStudent(){
        Student s = new Student();
        s.setName("周华");
        s.setAge(20);
        s,setSex("man");
        return s;
    }
}

相当于:

<bean id="student" class="com.xxx.domain.student">
	<property name="name" value="周华" />
    <property name="age" value="20" />
    <property name="sex" value="man" />
</bean>

3).@ImportResource:导入其他的xml配置文件

栗子:(applicationContext.xml文件)

<bean id="cat" class="com.xxx.domain.Cat">
    <property name="name" value="来福" />
    <property name="age" value="10" />
</bean>

配置类中:

@Configuration
@ImportResource("classpath:applicationContext.xml")
public class SpringConfig{}

4).@PropertyResource:读取属性配置文件。

栗子:

创建一个属性配置文件config.properties:

tiger.name=东北老虎
tiger.age=6

创建实体类:

@Component("tiger")
public class Tiger{
    @Value("${tiger.name}")
    private String name;
    @Value("${tiger.age}")
    private Integer age;
}

在配置文件中:

@Configuration
@PropertySource("classpath:config.properties")
@ComponentScan(basePackage = "com.xxx.domain")
public class SpringConfig{}

二.springboot框架入门


1.springboot特点


①.能够创建spring应用,具有内置的tomcat,jetty和Undertow服务器。

②.提供了 starter起步依赖,简化应用的配置。

比如使用Mybatis框架,原需要在Spring项目中配置Mybatis的SqlSessionFactory和dao的代理对象。在springboot项目中,只需要加入一个mybatis-spring-boot-starter依赖即可。

③其尽可能地配置了更多的第三方库。

2.创建项目方式


方式1:使用springboot自带的初始化器。

start.spring.io

方式2:使用国内的初始化器。

start.springboot.io

方式3:利用Maven创建项目(不详细赘述)。

3.注解介绍


1):@SpringBootApplication复合注解:其包括以下子注解。

@SpringBootConfiguration:

用来声明对象。

@EnableAutoConfiguration:

启用自动配置,把java对象配置好,注入到spring容器中。

@ComponentScan:

组件扫描器,用于找到注解。其默认扫描位置是该注解所在包以及其子包下。

4.springboot的核心配置文件


1)简介

配置文件的文件名:application

配置文件扩展名:

.properties:书写形式为 key=value

.yml:书写格式为 key:value

所在包:resources包下。


2)在配置文件中的设置

设置端口号与访问路径(properties文件)

#设置端口号
server.port=8082
#设置访问应用路径
server.servlet.context-path=/myBoot

设置端口号与访问路径(yml文件)

server:
  port:  8083
  servlet:
    context-path:/myBoot2

值得注意的一点是,每个层级关系差两个空格,不建议使用TAB,此外,冒号后面至少应有一个空格。yml文件的层次更为清晰。

如果在一个项目中,同时具有application.ymlapplication.properties,优先使用后者。


3)多环境配置

为什么使用多环境配置

多环境配置有 开发环境,测试环境,上线环境等等。

每个环境有不同的配置信息,例如端口,上下文件,数据库url,用户名,密码等等。

多环境配置可自由切换不同配置。

使用方式

创建多个配置文件,命名规则如下:

application-环境名称.properties或者application-环境名称.yml

例如:

①创建开发者环境配置文件:application-dev.xxx。

②创建测试者使用的环境配置文件:application-test.xxx。

在核心配置文件application.yml中激活要使用哪一个配置文件即可。

例如:

①创建开发者环境配置文件:application-dev.yml。

②创建测试者环境配置文件:application-test.yml。

③创建上线后环境配置文件:application-online.yml。

在主配置文件中的激活语法:

yml中

spring:
  profiles:
    active: 阶段名

properties中

spring-profiles-active=阶段名

比如在测试时:spring-profiles.active=test。


4)把配置文件数据映射为java文件

相关注解:@ConfigurationProperties

栗子:

配置文件application.properties

school.name=城关学校
school.address=中国

映射为java文件:

@Component
@ConfigurationProperties(prefix = "前缀")  //此处可写school
public class SchoolInfo{
    private String name;//对应配置文件中的前缀.name
    private String address;//同上
}

5)获取容器中对象

途径:通过SpringApplication.run(Application.class,args);的返回值获取容器。其返回值返回一个@ConfigurableApplicationContext接口(即@ApplicationContext的子接口)。


6)Runner接口

P28

作用:如果某程序需要在容器启动后执行一些内容,比如读取配置文件,数据库连接之类的,springboot提供了两接口来实现此功能。分别为 CommandLineRunnerApplicationRunner其执行时机为容器创建完成的时候,这个两个接口中都有run方法,我们只需要实现run方法即可。以上两个接口不同的地方在于,ApplicationRunner中run方法的参数为ApplicationArguments,而CommandLineRunner接口中的run方法参数为String数组。

三.Web组件


1.拦截器


定义:是SpringMVC中的一种对象,能拦截对Controller的请求。

分类:存在框架中系统的拦截器,也可以自定义拦截器,实现对请求的预先处理。

MVC中实现自定义拦截器的方法

①创建类实现SpringMVC框架的HandlerInterceptor接口。

②一般使用以下方法:

default boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) throw Exception{
    return true;//请求能被系统处理
}

③在SpringMVC的配置文件中,声明拦截器

<mvc:interceptors>
	<mvc:interceptor>
    	<mvc:path="url" />
        <bean class="拦截器类的全限定名称" />
    </mvc:interceptor>
</mvc:interceptors>

springboot中实现拦截器的方法

栗子:

编写拦截器:

public class selectInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request
                            ,HttpServletResponse response
                            ,Object handler) throws Exception{
        ......(拦截器内容)
            return true/false;
    }
}

配置拦截器:

@Configuration
public class MyAppConfig implements WebMvcConfigurer {
    //创建拦截器对象并将其注入容器
    @Override
    public void addInterceptors(InterceptorRegistry registry){
        //创建拦截器对象
        //LoginInterceptor是自建的一个拦截器类
        HandlerInterceptor interceptor = new LoginInterceptor();
        //指定拦截的请求uri地址
        String[] path = {"/user/**"};
        //指定不拦截的请求uri地址
        String[] excludePath = {"/user/login"};
        //添加拦截地址和非拦截地址
        registry.addInterceptor(interceptor)
            .addPathPatterns(path)
            .excludePathPatterns(excludePath);
    }
}

2.Servlet


使用SpringBoot时使用步骤

​ ①创建Servlet类继承HttpServlet

​ ②注册Servlet,让框架找到Servlet。

栗子:

创建一个servlet:

public class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req
                        ,HttpServletResponse resp)
        throws ServletException, IOException{
        (doGet内容)
    }
    @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();
    }
}

注册Servlet:

@Configuration
public class WebApplicationConfig {
    
    @Bean
    public ServletRegistrationBean registrationBean(){
        ServletRegistrationBean beans = new ServletRegistrationBean(new MyServlet,"/myWeb/test");
        //--------------或者--------------------
        ServletRegistrationBean beans = new ServletRegistrationBean();
        beans.setServlet(new MyServlet());
        //可加入多个访问地址
        beans.addUrlMappings("/login","/test",...);
        return beans;
    }
}

3.过滤器


定义:Filter是Servlet中的过滤器。

作用:处理请求,对请求的参数,属性进行调整。常用于处理字符编码。

使用步骤

​ ①创建自定义过滤器类。

​ ②注册Filter过滤器对象。

栗子:

创建一个自定义的过滤器:

public class myFilter implements Filter{
    @Override
    public void doFilter(ServletRequest servletRequest
            , ServletResponse servletResponse
            , FilterChain filterChain) throws IOException, ServletException {
        System.out.println("myFilter过滤器执行了!");
       (过滤器内容.....) filterChain.doFilter(servletRequest,servletResponse);
    }
}

注册过滤器:

@Configuration
public class myConfig{
    @Bean
    public FilterRegistrationBean registrationBean(){
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new myFilter());
        bean.addUrlPatterns("/myWeb/login","/myWeb/select");
        return bean;
    }
}

4.CharacterEncodingFilter的使用

使用步骤

​ ①配置字符集过滤器。

​ ②修改application.properties配置文件,为了使自定义的过滤器起作用。

栗子:

(方法一)

配置字符集过滤器:

@Configuration
public class WebSystemConfig {
    //注册Servlet
    public ServletRegistrationBean registrationBean(){
        ServletRegistrationBean reg = new ServletRegistrationBean();
        reg.setServlet(new myServlet);
        reg.addUrlMappings("/myWeb/test");
    }
    
    //配置过滤器
    public FilterRegistrationBean FilterRegistrationBean(){
        FilterRegistrationBean bean = new FilterRegitrationBean();
        //使用框架中的过滤器类
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        //指定编码方式
        filter.setEncoding("utf-8");
        //指定request,response都是用encoding进行编码
        filter.setForceEncoding(true);
        bean.setFilter(filter);
        bean.addUrlPatterns("/*");
        return bean;
    }
}

修改配置文件:

server.servlet.encoding.enabled=false

(方法二)

直接在第一个的基础上,修改系统的编码形式

#让系统的CharacterEncodingFilter生效
server.servlet.encoding.enabled=true
#指定使用的编码方式
server.servlet.encoding.charset=utf-8
#强制request,response都使用charset的编码方式
server.servlet.encoding.force=true

四.ORM操作MySQL


ORM:Object Relational Mapping(对象关系映射)。

作用:把面向对象的概念根数据库中表的概念对应起来。


1.Springboot继承mybaties

使用步骤

​ ①加入mybaties的起步依赖,完成对象的自动配置。

​ ②在pom中指定把src/main/java目录中的xml文件包含到classpath中。

​ ③创建实体类Student。

​ ④创建Dao接口StudentDao,创建一个查询学生的方法。

​ ⑤创建Dao接口对应的Mapping文件,xml文件,写sql语句、

​ ⑥创建Service层对象,创建StudentService接口和他的实现类,用dao对象的方法完成数据库的操作。

​ ⑦创建Controller对象,访问Service。

​ ⑧书写application.properties文件配置数据库的连接信息。


2.查找项目实战

利用springboot与mybatis框架进行数据库的查询操作。

1)创建数据库student

2)利用启动器创建项目

依赖项需加入MVC MySQL,JDBC等。

3)pom文件指定配置文件扫描范围

 <resources>
      <resource>
           <directory>src/main/java</directory>
      	<includes>
           <include>**/*.xml</include>
      	</includes>
      </resource>
 </resources>

4)创建实体类Student:(entity包下)

public class Student {
    private Integer id;
    private String name;
    private Integer age;
    (toString,set,get方法省略)
}

5)创建dao接口和sql映射:(dao包下)

StudentDao文件

@Mapper
public interface StudentDao {
    //查询学生功能
    Student selectStudent(@Param("stuId") Integer id);
}

StudentDao.xml文件

<mapper namespace="com.shawn.dao.StudentDao" >
    <select id="selectStudent" resultType="com.shawn.entity.Student" >
        select * from student where id=${stuId}
    </select>
</mapper>

6)创建service层接口及其实现类(service包下)

StudentService接口

public interface StudentService {
    Student selectStudent(Integer id);
}

StudentServiceImpl类(impl包下)

@Service
public class StudentServiceImpl implements StudentService {
    @Resource
    private StudentDao studentDao;
    @Override
    public Student selectStudent(Integer id) {
        Student student = studentDao.selectStudent(id);
        return student;
    }

7)创建controller层及其类(controller包下)

@Controller
public class StudentController {
    @Resource
    private StudentService studentService;
    @RequestMapping("/student/selectById")
    @ResponseBody
    public Student selectStudent(Integer id){
        Student student = studentService.selectStudent(id);
        return student;
    }

8)书写配置文件的数据库连接信息(application.properties文件中)

server.port=9001
server.servlet.context-path=/myWeb

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springbootdb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123456

9)通过Application类运行,并在页面中访问

访问 http://localhost:9001/myWeb/student/selectById?id=() 即可。

错误分析:初始访问时未附带后面的 id=(),发生了500的状态码异常,原因为传值进去id为空,导致后续框架操作无法执行!后续应注意!


3.相关注解解析

方式一:@Mapper注解。

位置:放在dao接口的上面,每个接口都需要该注解

方式:用于创建修饰类的代理对象。

方式二:@MapperScan注解。

位置:放在启动类Application上面,仅需要一个注解

属性:basePackages中值为需要扫描的包名数组。

@SpringBootApplication
@MapperScan(basePackages = {"com.shawn.dao",...})
public class Application {...}

采用mapper文件与原dao文件分开管理。

通常将mapper文件放入src/main/resource/mapper包中

与此同时,需修改pom.xml中的resource标签:

<resources>
      <resource>
           <directory>src/main/resources</directory>
      	<includes>
           <include>**/*.*</include>
      	</includes>
      </resource>
 </resources>

在application.properties配置文件中指定mapper文件的目录位置:

#指定mapper文件位置
mybatis.mapper-locations=classpath:mapper/*.xml
#指定日志
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

4.事务的使用


Spring框架中的事务回顾:

​ 1)管理事务的对象:事务管理器(接口)。

比如在使用jdbc或mybatis访问数据库时,使用的事务管理器是DataSourceTransactionManager

​ 2)声明事务:在xml配置文件中或者使用注解说明事务控制的内容。

控制事务:隔离级别,传播行为,超时时间...

​ 3)事务处理方式:

​ ①spring框架中的@Transactional注解

​ ②aspectj框架可在xml配置文件中声明事务控制的内容。


springboot框架中的事务

使用步骤

​ ①在业务方法上加@Transactional,加入注解后,方法就有事务功能了。

​ ②在主启动类上加@EnableTransactionManager注解。


插入操作实现实例

题目要求,在上述查找实例中添加插入学生信息操作。

准备实体类,pom文件中的配置等仅作简述,不再列举代码。

1).准备数据库,实体类(model包下)均与查找操作类似。

2)在application.properties主配置文件中添加数据库连接信息以及指定mapper文件的位置等等。

server.port=9001
server.servlet.context-path=/myWeb

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springbootdb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123456
#指定mapper文件位置
mybatis.mapper-locations=classpath:mapper/*.xml
#指定日志
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

3)创建dao层的接口及其映射文件。(mapper包下)

dao层接口StudentMapper:

public interface StudentMapper {
    //插入学生
    int insertStudent(Student student);
}

dao层映射文件StudentMapper.xml:(resources/mapper下)

<mapper namespace="com.shawn.mapper.StudentMapper">
    <insert id="insertStudent">
        insert into student(id,name,age) values(#{id},#{name},#{age})
    </insert>
</mapper>

4)创建Service层的接口和实现类:(service包下)

接口StudentService:

public interface StudentService {
    int insertStudent(Student student);
}

实现类StudentServiceImpl:(service/impl包下)

@Service
public class StudentServiceImpl implements StudentService {
    @Resource
    StudentMapper studentMapper ;
    @Override
    @Transactional
    public int insertStudent(Student student) {
        int rows = studentMapper.insertStudent(student);
        return rows;
    }
}

5)创建Controller层的类:(controller包下)

@Controller
public class StudentController {
    @Resource
    StudentService studentService ;
    @RequestMapping("/student/insert")
    @ResponseBody
    public String insertStudent(Student student){
        int rows = studentService.insertStudent(student);
        return "插入数据的行数rows="+rows;
    }
}

6)主启动类加注解:

@SpringBootApplication
@EnableTransactionManagement
@MapperScan(basePackages = "com.shawn.mapper")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }
}

五.接口架构风格---RESTful

1.API介绍

概念:API(Application Programming Interface,应用程序接口)是一些预先定义的接口(如 函数,HTTP接口),或指软件系统不同组成部分衔接的规定。用来提供应用程序和开发人员基于某软件或硬件访问的一组例程,而又无需访问其源码,或者理解内部工作机制的细节。

实例:Servlet,Controller的url,i奥永其他程序的函数等等。


2.架构风格RESTful

概念:API组织方式。

案例:http://localhost:8080/myWeb/addStudent?id=20&name=哈哈&age=28就是一个传统的架构风格。


RESTful (Representational State Transfer,表现层状态转移) :是一种接口的架构风格和设计的理念,非标准非强制。

优点

Ⅰ.轻量,直接基于 http,不再需要任何别的诸如消息协议 get/post/put/delete 为 CRUD 操作 Ⅱ.面向资源,一目了然,具有自解释性。 Ⅲ.数据描述简单,一般以 xml,json 做数据交换。 Ⅳ.无状态,在调用一个接口(访问、操作资源)的时候,可以不用考虑上下文,不用考虑当前状态,极大的降低了复杂度。 Ⅴ.简单、低耦合

要素

对资源的操作:(CURD(create update retrieve delete))

操作资源的请求方式

​ ①GET:查询资源

​ ②POST:创建资源

​ ③PUT:更新资源

​ ④DELETE:删除资源

简而言之,RESTful风格是 使用url表示资源,使用http动作操作资源

3.RESTful的注解:


​ ①@PathVariable:从url中获取数据。

案例:

@RestController
public class myRestController{
    @GetMapping("/student/{stuId}")
    public String queryStudent(@PathVariable("stuId") Integer id){
        return "查询学生信息的id="+id;
    }
}

​ 从而框架能获取到用户在url中输入的{stuId}信息。

​ ※当mapping值变量名与形参名一样时,可省略注解后的括号。

​ ②@GetMapping:支持get请求方式。

※该注解等效于@RequestMapping(method=RequestMethod.GET)。

​ ③@PostMapping:支持post请求方式。

※该注解等效于@RequestMapping(method=RequestMethod.POST)。

案例:

@PostMapping("student/{name}/{age}")
public String createStudent(@PathVariable String name,
                           @PathVariable Integer age){
    return "创建学生资源student:name="name+"#age="+age;
}

​ ④@PutMapping:支持put请求方式。

※该注解等效于@RequestMapping(method=RequestMethod.PUT)。

​ ⑤DeleteMapping:支持delete请求方式。

※该注解等效于@RequestMapping(method=RequestMethod.DELETE)。

​ ⑥@RestController:符合注解。其包括@Controller 和 @ResponseBody 的组合。在类的上面使用了该注解,相当于所以方法上添加了 @ResponseBody 注解。


在页面中支持put,delete方式的访问

在springMVC中有一个过滤器,支持post请求转为put,delete。

过滤器:org.springframework.web.filter.HiddenHttpMethodFilter

实现步骤:

​ 1.在application.yml/properties中开启使用过滤器。

​ 2.在请求页面中,配置_method参数的name,value。请求是post。

案例:

<form action="student/test" method="post">
    <input type="hidden" name="_method" value="delete/put">
    <input type="submit" value="xxx">
</form>

文章末尾传送点