SpringBoot一统江湖

一 SpringBoot简介

SpringBoot是Spring框架的一个新子项目 用于创建Spring4.0项目 它的开发始于2013年 2014年4月发布1.0.0版本 它可以自动配置Spring的各种组件 并不依赖代码生成和XML配置文件 SpringBoot也提供了对于常见场景的推荐组件配置 SpringBoot可以大大提升使用Spring框架时的开发效率 使用SpringBoot可以轻松创建独立运行的程序 非常容易构建独立的服务组件 是实现分布式架构 微服务架构利器

 

二 SpringBoot优点

1. 轻松创建独立的Spring应用程序

2. 内嵌Tomcat Jetty等web容器 不需要部署WAR文件

3. 提供一系列的starter 来简化的Maven配置 不需要添加很多依赖

4. 开箱即用 尽可能自动配置Spring

 

三 SpringBoot初体验

1. 新建一个Maven项目 注意不需要webapp文件夹及子文件夹和web.xml

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.hy.springboot</groupId>
    <artifactId>springboot-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.4.RELEASE</version>
    </parent>

    <!-- 定义依赖版本号 -->
    <properties>
        <mysql-connector-java.version>8.0.11</mysql-connector-java.version>
        <druid.version>1.1.10</druid.version>
        <mybatis-spring-boot-starter.version>2.1.3</mybatis-spring-boot-starter.version>
        <pagehelper-spring-boot-starter.version>1.3.0</pagehelper-spring-boot-starter.version>
    </properties>

    <!-- 管理jar版本号 -->
    <dependencyManagement>
        <dependencies>
            <!-- mysql -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql-connector-java.version}</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>${druid.version}</version>
            </dependency>
            <!-- mybatis -->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis-spring-boot-starter.version}</version>
            </dependency>
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper-spring-boot-starter</artifactId>
                <version>1.3.0</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <!-- web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- aop -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <!-- mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>
        <!-- mybatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
        </dependency>
    </dependencies>

    <build>
        <!-- 允许mybatis的mapper.java和mapper.xml在同一目录 -->
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.yml</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.yml</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>

        <!-- 打包名称 -->
        <finalName>one</finalName>
        <plugins>
            <!-- 编译 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <!-- spring boot -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>com.hy.springboot.Application</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

sql

-- 用户表
CREATE TABLE user (
    id INT PRIMARY KEY AUTO_INCREMENT COMMENT '用户id',
    username VARCHAR(32) COMMENT '用户名',
    money DOUBLE COMMENT '用户余额'
);

INSERT INTO user VALUES (1, '曹操', 8000);
INSERT INTO user VALUES (2, '孙权', 8000);
INSERT INTO user VALUES (3, '刘备', 8000);
INSERT INTO user VALUES (4, '诸葛亮', 5000);
INSERT INTO user VALUES (5, '司马懿', 5000);
INSERT INTO user VALUES (6, '张飞', 0);
INSERT INTO user VALUES (7, '关羽', 0);
INSERT INTO user VALUES (8, '马超', 1000);
INSERT INTO user VALUES (9, '黄忠', 1000);
INSERT INTO user VALUES (10, '赵云', 3000);

2. 创建配置文件 resources/application.yml

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/demo_hy?characterEncoding=utf8&useSSL=false
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: root
    type: com.alibaba.druid.pool.DruidDataSource
    max-active: 20
    min-idle: 5
  servlet:
    multipart:
      max-file-size: 5Mb
      max-request-size: 10MB
mybatis:
  type-aliases-package: com.hy.springboot.model
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
pagehelper:
  helper-dialect: mysql
  reasonable: true
  support-methods-arguments: true
  params: count=countSql
server:
  port: 8081
  servlet:
    context-path: /

3. 创建实体类 com.hy.springboot.model.User com.hy.springboot.model.PageWrapper com.hy.springboot.model.HttpError

public class User implements Serializable {

    private Integer id;
    private String username;
    private Double money;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Double getMoney() {
        return money;
    }

    public void setMoney(Double money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", money=" + money +
                '}';
    }
}
public class PageWrapper implements Serializable {

    private Long total;
    private List list;

    public PageWrapper() {}

    public PageWrapper(Long total, List list) {
        this.total = total;
        this.list = list;
    }

    public Long getTotal() {
        return total;
    }

    public void setTotal(Long total) {
        this.total = total;
    }

    public List getList() {
        return list;
    }

    public void setList(List list) {
        this.list = list;
    }
}
public class HttpError extends Exception {

    private int code;
    private String message;

    public HttpError() {}

    public HttpError(int code, String message) {
        this.code = code;
        this.message = message;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    @Override
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    public String toString() {
        return "HttpError{" +
                "code=" + code +
                ", message='" + message + '\'' +
                '}';
    }
}

4. 自定义文件上传实现类 com.hy.springboot.resolver.PostAndPutMultipartResolver 解决客户端(android ios...) PUT提交文件表单异常

public class PostAndPutMultipartResolver extends StandardServletMultipartResolver {

    @Override
    public boolean isMultipart(HttpServletRequest request) {
        if ("POST".equalsIgnoreCase(request.getMethod()) || "PUT".equalsIgnoreCase(request.getMethod())) {
            return StringUtils.startsWithIgnoreCase(request.getContentType(), "multipart/");
        }
        return false;
    }
}

5. 配置文件上传实现类 com.hy.springboot.config.MultipartResolverConfig

@Configuration
public class MultipartResolverConfig {

    @Bean(name = "multipartResolver")
    public MultipartResolver multipartResolver() {
        return new PostAndPutMultipartResolver();
    }
}

6. 创建拦截器 com.hy.springboot.interceptor.Interceptor

public class Interceptor implements HandlerInterceptor {

    // Controller执行前调用此方法
    // 返回true继续执行 返回false中止执行
    // 这里可加入登录校验 权限拦截等
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println(" ========== preHandle ========== ");
        // 放行
        return true;
    }

    // Controller执行后 且未返回视图前 调用此方法
    // 这里可在返回用户前对模型数据进行加工处理 比如这里加入公用信息以便页面显示
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {}

    // Controller执行后 且视图返回后 调用此方法
    // 这里可得到执行Controller时的异常信息
    // 这里可记录操作日志
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {}
}

7. 配置拦截器 com.hy.springboot.config.InterceptorConfig

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new Interceptor()).addPathPatterns("/**"); //拦截所有
    }
}

8. 配置异常处理器 com.hy.springboot.exception.HttpErrorResolver

@ControllerAdvice
public class HttpErrorResolver {

    @ExceptionHandler(RuntimeException.class)
    @ResponseBody
    public HttpError resolveException(Exception e) {
        HttpError error = e instanceof HttpError ? (HttpError) e : new HttpError(-1, "未知异常");
        return error;
    }
}

9. 配置数据源 com.hy.springboot.config.DruidConfig

@Configuration
public class DruidConfig {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource") //将application.yml配置文件中前缀为spring.datasource的属性注入到DruidDataSource同名参数中
    public DataSource dataSource() {
        return new DruidDataSource();
    }
}

10. 配置AOP com.hy.springboot.aop.LogAspect

@Component
@Aspect
public class LogAspect {

    /**
     * 声明公共切入点
     * expression(表达式): 切点表达式
     * * com.hy.springboot.controller..*.*(..)
     * * = 任意返回值
     * com.hy.springboot.controller. = com.hy.springboot.controller包和所有子包
     * .*.* = .任意类.任意方法名
     * (..) = 任意参数
     */
    @Pointcut("execution(* com.hy.springboot.controller..*.*(..))")
    public void pointcut() {}

    /**
     * 前置通知 在方法执行前执行 如果通知抛出异常 阻止方法运行
     * @param joinPoint 连接点
     */
    @Before("pointcut()")
    public void before(JoinPoint joinPoint) {
        System.out.println("前置通知 JoinPoint = " + joinPoint.toString());
        // 请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String url = request.getRequestURL().toString();
        String method = request.getMethod();
        System.out.println("url = " + url);
        System.out.println("method = " + method);
        Enumeration<String> enu = request.getParameterNames();
        while (enu.hasMoreElements()) {
            String name = enu.nextElement();
            System.out.println(name + "=" + request.getParameter(name));
        }
    }

    /**
     * 后置通知 方法正常返回后执行 可以获得方法返回值 如果方法中抛出异常 通知无法执行
     * @param joinPoint 连接点
     * @param ret 方法返回值
     */
    @AfterReturning(value = "pointcut()", returning = "ret")
    public void afterReturning(JoinPoint joinPoint, Object ret) {
        System.out.println("后置通知 ret = " + ret + " JoinPoint = " + joinPoint.toString());
    }
}

11. 配置启动器 com.hy.springboot.Application

@SpringBootApplication
@MapperScan("com.hy.springboot.mapper")
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

12. 创建mapper接口 com.hy.springboot.mapper.UserMapper

public interface UserMapper {
    
    List<User> selectUserList();

    Integer updateUserMoney(Map map);
}

13. 创建mapper映射文件 com.hy.springboot.mapper.UserMapper.xml

<?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.hy.springboot.mapper.UserMapper">
    <select id="selectUserList" resultType="User">
        SELECT *
        FROM user
    </select>

    <update id="updateUserMoney" parameterType="HashMap">
        UPDATE user
        SET money = money + #{money}
        WHERE id = #{id}
    </update>
</mapper>

14. 创建service接口 com.hy.springboot.service.IUserService

public interface IUserService {

    List<User> selectUserList();

    PageWrapper selectUserList(Integer pageNum, Integer pageSize);

    Boolean updateUserMoney(Map map1, Map map2);
}

15. 创建service实现类 com.hy.springboot.service.imp.UserService

@Service
@Transactional
public class UserService implements IUserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public List<User> selectUserList() {
        return userMapper.selectUserList();
    }

    @Override
    public PageWrapper selectUserList(Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<User> userList = userMapper.selectUserList();
        PageInfo<User> pageInfo = new PageInfo<>(userList);
        return new PageWrapper(pageInfo.getTotal(), userList);
    }

    @Override
    public Boolean updateUserMoney(Map map1, Map map2) {
        Integer integer1 = userMapper.updateUserMoney(map1);
        int i = 3 / 0; //模拟异常
        Integer integer2 = userMapper.updateUserMoney(map2);
        return 0 != integer1 && 0 != integer2;
    }
}

16. 创建控制器 com.hy.springboot.controller.TestController

@RestController
@RequestMapping("/test")
public class TestController {

    @Autowired
    private IUserService userService;

    @RequestMapping("/tm")
    public Boolean tm() {
        Map<String, Object> map1 = new HashMap<>();
        map1.put("id", 6);
        map1.put("money", -1000.0);
        Map<String, Object> map2 = new HashMap<>();
        map2.put("id", 7);
        map2.put("money", +1000.0);
        return userService.updateUserMoney(map1, map2);
    }

    @RequestMapping("/selectUserList")
    public List<User> selectUserList() {
        return userService.selectUserList();
    }

    @GetMapping("/selectUserList/{page}/{size}")
    public PageWrapper selectUserList(@PathVariable Integer page, @PathVariable Integer size) {
        return userService.selectUserList(page, size);
    }

    /** RESTful 只进行演示 没有做数据持久化 **/

    @PostMapping("/insert")
    public Map insert(String name) {
        Map<String, Object> map = new HashMap<>();
        map.put("name", name);
        return map;
    }

    @PostMapping("/insertX")
    public Map insertX(String name, MultipartFile file) throws Exception {
        Map<String, Object> map = new HashMap<>();
        map.put("name", name);
        map.put("fileSize", file.getSize()); //建议使用文件服务器保存
        return map;
    }

    @DeleteMapping("/delete/{id}")
    public Map delete(@PathVariable Integer id, String name) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", id);
        map.put("name", name);
        return map;
    }

    @PutMapping("/update/{id}")
    public Map update(@PathVariable Integer id, String name) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", id);
        map.put("name", name);
        return map;
    }

    @PutMapping("/updateX/{id}")
    public Map updateX(@PathVariable Integer id, String name, MultipartFile file) throws Exception {
        Map<String, Object> map = new HashMap<>();
        map.put("id", id);
        map.put("name", name);
        map.put("fileSize", file.getSize()); //建议使用文件服务器保存
        return map;
    }

    @GetMapping("/select/{id}")
    public Map select(@PathVariable Integer id, String name) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", id);
        map.put("name", name);
        return map;
    }
}

启动项目 访问 http://localhost:8081/test/selectUserList

android客户端核心代码

public interface Api {

    @POST("/test/insert")
    @FormUrlEncoded
    Call<ResponseBody> insert(@Field("name") String name);

    @POST("/test/insertX")
    @Multipart
    Call<ResponseBody> insertX(@Part MultipartBody.Part name, @Part MultipartBody.Part file);

    @DELETE("/test/delete/{id}")
    Call<ResponseBody> delete(@Path("id") Integer id, @Query("name") String name);

    @PUT("/test/update/{id}")
    @FormUrlEncoded
    Call<ResponseBody> update(@Path("id") Integer id, @Field("name") String name);

    @PUT("/test/updateX/{id}")
    @Multipart
    Call<ResponseBody> updateX(@Path("id") Integer id, @Part MultipartBody.Part name, @Part MultipartBody.Part file);

    @GET("/test/select/{id}")
    Call<ResponseBody> select(@Path("id") Integer id, @Query("name") String name);
}
private void insert() {
    Call<ResponseBody> call = mApi.insert("祎哥哥");
    call.enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {}

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {}
    });
}

private void insertX() {
    MultipartBody.Part name = MultipartBody.Part.createFormData("name", "祎哥哥");
    RequestBody body = RequestBody.create(MediaType.parse("application/octet-stream"), card("text.txt"));
    MultipartBody.Part file = MultipartBody.Part.createFormData("file", "text.txt", body);
    Call<ResponseBody> call = mApi.insertX(name, file);
    call.enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {}

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {}
    });
}

private void delete() {
    Call<ResponseBody> call = mApi.delete(3, "黄祎");
    call.enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {}

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {}
    });
}

private void update() {
    Call<ResponseBody> call = mApi.update(3, "黄祎");
    call.enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {}

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {}
    });
}

private void updateX() {
    MultipartBody.Part name = MultipartBody.Part.createFormData("name", "黄祎");
    RequestBody body = RequestBody.create(MediaType.parse("application/octet-stream"), card("text.txt"));
    MultipartBody.Part file = MultipartBody.Part.createFormData("file", "text.txt", body);
    Call<ResponseBody> call = mApi.updateX(3, name, file);
    call.enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {}

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {}
    });
}

private void select() {
    Call<ResponseBody> call = mApi.select(3, "黄祎");
    call.enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {}

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {}
    });
}

 

posted @ 2020-09-28 09:26  梦三  阅读(2403)  评论(0编辑  收藏  举报