Springboot使用入门

在整合SSM的过程中,发现会花很多时间去整理配置文件,如spring相关的的applicationContext.xml,springweb相关的springmvc.xml,mybatis相关的sqlConfig.xml和sql映射文件,以及web.xml中的配置等,比较繁琐,配置也容易出问题。另外虽然使用maven管理包可以解决以前手动粘贴复制导包的窘境,但是maven导包还需要考虑包之间是否有冲突是否兼容的问题。以上的缺点spring考虑到了就推出了springboot,它的基本理念是"约定大于配置",大大简化开发人员前期的配置,让更多精力用于开发,下面简单入门记录一下。

传统SSM开发痛点

(1)pom.xml需要配置大量依赖,繁琐且容易出错,需考虑版本号、版本兼容、版本冲突的问题。

(2)测试需要有容器的支持,如打包发送到tomcat中,无法独立运行,不利于开发测试。

Springboot简介

springboot是一个基于spring的项目快速构建工具,可以大大提高项目构建和开发的效率,它向前承接了SSM的开发,使其变得简化,向后则是springcloud微服务的基础。它具有如下优点。

(1)pom中需要配置的文件大大减少,利用了pom文件的继承和传递技术,会有一些顶级父pom文件给我们使用,如下就是web相关的顶级父pom依赖。

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

(2)"约定大于配置",不做任何配置或只需要少量的配置就可以开始开发,会根据导入的包,自动生成配置文件。

(3)内置servlet容器,web开发测试像独立运行一个main方法一样简单。

Springboot入门案例

使用IDEA创建一个maven工程,使用quick start方式启动。

(1)pom文件,spring-boot-starter-parent这个pom文件是springboot的,里面定义的内容被当前pom文件导入,包含了当前springboot下最合适的jar包版本,无需再担心版本问题。此外它还定义了大量声明式依赖,如果需要引入需要手动添加。

    <!-- 继承springboot-parent,引入springboot的父pom文件 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
    </parent>

  <dependencies>

    <!-- 以前需要配置很多依赖包,这里只需要配置一个starter-web,就会将spring相关的包自动导入,非常简便 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
  </dependencies>

(2)resources下无需写配置文件,就可以运行springboot。

(3)书写启动类,使用@SpringBootApplication复合注解,具体参考代码注释。

package com.boe;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * 开发主类,其中包含main方法
 */
@SpringBootApplication
public class SpringbootDemo01 {

    /**
     * @SpringBootApplication注解是一个复合注解,它由如下几部分组成
     * @SpringBootConfiguration:自动读取springboot配置文件(它也是一个复合注解,包含@Configuration注解),如application.properties,banner.txt,bootstrap.properties
     * @EnableAutoConfiguration:根据当前引入的包自动生成配置信息,注解工作时会加载spring-boot-autoconfigure-1.5.9.RELEASE.jar包,解析META-INF/下的spring-factories配置文件
    *  @ComponentScan:默认将当前类所在包及其子孙包,加入到springIOC的包扫描,相当如<context:component-scan></context:component-scan>的配置
     */

    public static void main(String[] args) {
        System.out.println("hello springboot");
        //启动springboot,加载类时发现其有@SpringBootApplication注解,触发注解的功能
        //完成自动读取配置文件,自动生成配置文件和添加包扫描等功能。
        SpringApplication.run(SpringbootDemo01.class,args);
    }
}

(4)写一个controller控制类

package com.boe.controller;

import com.boe.service.FirstService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/first") //测试springmvc
public class FirstController {

    //自动注入service,测试spring di
    @Autowired
    FirstService service;

    @ResponseBody
    @RequestMapping("/test01.action")
    public String test01(){
        System.out.println("controller is running");
        //service
        service.print();
        return "hello springboot";
    }
}

(5)写一个service类

package com.boe.service;

import org.springframework.stereotype.Service;

@Service("service")
public class FirstService {

    public void print(){
        System.out.println("service is running");
    };

}

(6)开启启动类,发现web可以正常访问,其中访问的端口号(8099)和context-path(yangchaolin)可以单独设置的。

Springboot配置

虽然springboot无需配置也可以启动,但是必要时也可以通过配置来修改默认配置。

(1)application.properties或application.yml。

它是springboot的核心配置文件,有两种格式,均可以使用,后者yml容易出错,需要注意空格。

properties配置:

# 配置端口号
#server.port=8099
# 内置servlet运行时使用的应用名
#server.context-path=/yangchaolin

yml配置,注意格式:

# 书写非常严格,port和context-path前后都有空格
server:
 port: 8099
 context-path: /yangchaolin


# 可以配置属性,使用@Value可以将值引用

id: 2
name: herry
age: 36

(2)banner横幅

可以设置springboot启动时的字符画,如我修改成了clyang。

       .__
  ____ |  | ___.__._____    ____    ____
_/ ___|  |<   |  |\__    /      / ___
  \___|  |_\___  | / __ |   |  / /_/  >
 \___  >____/ ____|(____  /___|  /\___  /
     /     /          /     //_____/

(3)bootstrap.properties

用来配置加载系统配置,加载顺序优先于application.xml或application.yml,后续补充

常用注解

springboot下使用@Configuration可以将当前类作为配置类,类似applicationContext.xml,可以配合其他注解进行使用。

(1)@Configuration+@ComponentScan(包名),可以指定包扫描,如果不指定就将当前类所在包及其子孙包加入包扫描,一般用于扫描dao层的mapper包。

package com.boe.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * 当前包需要放在SpringbootDemo01所在包及其子包下面,需要被扫描到才能使用@Configuration注解生效
 */
@Configuration
@ComponentScan("com.baidu")
public class MyConfig {
    /**
     * @Configuration 理解为以前spring配置文件applicationContext.xml
     * @ComponentScan("com.baidu") 理解为以前的<context:component-scan base-package="com.baidu" />
     */
}

(2)@Configuration+@Bean,可以将方法返回的对象注册为bean交给spring管理,后续可以调用,如springcloud微服务调用使用的RestTemplate就用这种方式创建。

package com.boe.config;

import com.boe.domain.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 测试使用@Bean注解
 */
@Configuration
public class UserConfig {
    //使用@Bean,让其返回一个bean,相当如配置<bean id="" class="">
    @Bean("user") //可以指定bean id
    public User getUserInstance(){
        return new User();
    }
}

controller测试类

package com.boe.controller;

import com.boe.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 测试@Bean的controller
 */
@Controller
@RequestMapping("/user")
public class UserController {

    //测试是否user已经加入到spring bean中
    @Autowired
    User user;

    @ResponseBody
    @RequestMapping("/test01.action")
    public String test01(){
        System.out.println(user);
        return "user已经纳入spring管理";
    }
}
View Code

测试结果,访问地址,控制台打印出user对象,说明配置生效。

浏览器端

控制台端

(3)@Value,可以将核心配置文件中读取到的属性,通过@Value("${属性名}")的方式注入。

package com.boe.domain;

import org.springframework.beans.factory.annotation
.Value;

/**
 * 测试@Bean注解的实体类
 */
public class User {

    //可以使用@Value直接导入值
    //@Value("1")
    @Value("${id}")
    private int id;
    //@Value("messi")
    @Value("${name}")
    private String name;
    //@Value("32")
    @Value("${age}")
    private int age;

    public User() {
    }

    public User(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
......省略
}

在上面的基础上,在核心配置文件中添加属性值,再次测试发现导入了数值。

# 可以配置属性,使用@Value可以将值引用

id: 2
name: herry
age: 36

控制台输出了实际值,ok。

(4)@ImportResource,可以额外加载一个配置文件使用。

package com.boe.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;

/**
 * 测试使用@ImportResource注解
 */
@Configuration
@ImportResource(locations = "classpath:/myspring.xml") //读取自己定义的spring配置文件
public class DeptConfig {

}

其中myspring.xml配置信息就是配置了一个bean。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 测试@ImportResource注解 -->
    <bean id="dept" class="com.boe.domain.Dept" ></bean>

</beans>
View Code

测试的控制类

package com.boe.controller;

import com.boe.domain.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 测试使用@ImportResource注解
 */
@Controller
@RequestMapping("/dept")
public class DeptController {

    //注入dept
    @Autowired
    Dept dept=null;

    @ResponseBody
    @RequestMapping("/test01.action")
    public String test01(){
        System.out.println(dept);
        return "使用@ImportResource注解读取自定义配置文件生效";
    }

}
View Code

浏览器访问后,控制台和浏览器都正常输出,ok。

浏览器端

控制台端

springboot整合mybatis 

ssm里springmvc和spring是一家的,但是mybatis不是,因此需要单独拿出来整合。

(1)pom文件需要添加如下配置。

    <!-- mybatis整合需要单独导包 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.0.8</version>
    </dependency>

    <dependency>
      <groupId>org.mybatis.spring.boot</groupId>
      <artifactId>mybatis-spring-boot-starter</artifactId>
      <version>1.3.0</version>
    </dependency>

    <!--数据源使用德鲁伊-->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.0.14</version>
    </dependency>

(2)application.properties中配置数据库连接

# 指定驱动名
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# 指定url
spring.datasource.url=jdbc:mysql://localhost:3306/mydb2
# username
spring.datasource.username=root
# password
spring.datasource.password=root
# mybatis映射文件地址,idea放在resource/mapper下
mybatis.mapper-locations=classpath:mappers/*.xml
# 配置包的别名 ?
# mybatis.type-aliases-package=com.boe.domain
# 是否启动驼峰命名规则
mybatis.configuration.map-underscore-to-camel-case=false

(3)指定映射文件和对应接口

映射文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.boe.dao.UserMapper">

<!--如果设置了包的别名,可以省略为User--> <select id="findUser" resultType="com.boe.domain.User"> SELECT * FROM user; </select> </mapper>

对应接口

package com.boe.dao;

import com.boe.domain.User;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository("usermapper")
public interface UserMapper {
    public List<User> findUser();
}

(4)启动类中使用@MapperScan添加接口扫描

package com;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.boe.dao") //扫描包,UserMapper就在这个包下。
public class MainApp {
    public static void main(String[] args) {
        //启动springboot
        SpringApplication.run(MainApp.class,args);
        System.out.println("spring boot已启动");
    }
}

测试,以下为service层和controller层。

controller层

package com.boe.controller;

import com.boe.domain.User;
import com.boe.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;


@Controller
@RequestMapping("/user")
public class UserController {

    //注入service层
    @Autowired
    UserService userService = null;

    //查询user
    @ResponseBody
    @RequestMapping("/findUser.action")
    public List<User> findUser() {
        List<User> user = userService.queryUser();
        System.out.println("controller is runnint");
        System.out.println(user);
        return user;
    }
}
View Code

service层

package com.boe.service;

import com.boe.dao.UserMapper;
import com.boe.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service("userService")
public class UserService {

    //注入mapper
    @Autowired
    UserMapper userMapper=null;

    //查询user
    public List<User> queryUser(){
        System.out.println("service is running");
        return userMapper.findUser();
    };
}
View Code

启动springboot后,访问对应地址,发现能访问到db,控制台输出结果。

浏览器端

控制台端

springboot中使用jsp

springboot原生视图不是使用jsp实现的,如果配置视图解析器访问jsp,浏览器不知道如何处理这个文件,会直接下载处理,为了能让springboot能使用jsp,需要在pom文件中添加如下依赖,如果还涉及json返回的,还需要添加jackson相关的包。

    <!--springboot内置tomcat不支持jsp,需要导入如下包-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
      <!-- 部署war包需要将其设置provided -->
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>javax.servlet.jsp.jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>

    <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-jasper</artifactId>
      <version>7.0.52</version>
      <scope>provided</scope>
    </dependency>

    <!--springboot内置tomcat不支持jsp,需要导入如上包-->

  <!-- json字符串返回相关包 -->
  <dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-core</artifactId>
  <version>2.8.8</version>
  </dependency>

  <dependency>
   <groupId>com.fasterxml.jackson.core</groupId>
   <artifactId>jackson-databind</artifactId>
  <version>2.8.8</version>
  </dependency>

配置对应视图解析器。

spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp

测试controller类

package com.boe.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/jsp")
public class JspController {
    @RequestMapping("/test01.action")
    public String test01(Model model){
        System.out.println("jsp controller is running");
        //默认保存在request域中
        model.addAttribute("name","messi");
        return "test";
    }
}
View Code

测试用jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>test jsp</title>
</head>
<body>
    <h2>this is jsp from springboot</h2>
    <h2>${name}</h2>
</body>
</html>

访问jsp页面测试。

 springboot项目部署注意事项

springboot项目测试是在内置的容器中运行的, 打成war包在tomcat运行会出现动态资源访问不到的情况,出现这种情况需要在启动类添加如下配置。

(1)添加@ServletComponentScan注解

(2)启动类需要继承自SpringBootServletInitializer类,通过类的doc文档可以查看到最后提示如果需要部署war包,需要它。

Note that a WebApplicationInitializer is only needed if you are building a war file and deploying it. If you prefer to run an embedded container then you won't need this at
all

启动类

package com;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;

import javax.servlet.annotation.ServletSecurity;

@SpringBootApplication
@MapperScan("com.boe.dao") //配置扫描dao层接口
@ServletComponentScan //配置这个注解打war包才可以运行,并让如下类继承自SpringBootServletInitializer
public class MainApp extends SpringBootServletInitializer {
    public static void main(String[] args) {
        SpringApplication.run(MainApp.class,args);
        System.out.println("spring boot已启动");
    }
}

(3)打包类型选择war,打包后扔tomcat容器运行不能访问动态资源的问题会解决。

以上对springboot入门的整理,springboot比较适合单体项目的快速开发,如果需要做大型分布式项目需要用到springcloud,后续添加。

参考博文:

(1)https://blog.csdn.net/snow_7/article/details/88391192

(2)https://www.cnblogs.com/youngchaolin/p/11825510.html 依赖传递

原文地址:https://www.cnblogs.com/youngchaolin/p/11948838.html