springboot的特性简化spring

一.概述

         Spring Boot 之所以能大幅简化 Spring 开发,核心在于其 **“约定优于配置”** 的设计理念,通过一系列特性消除了传统 Spring 中繁琐的配置工作。

        约定大于配置即使用springboot框架自己的默认的规则,无需手动开发,如果需要特定功能,自定义配置即可。这样便可减少重复配置的书写,因为大多数配置都是固定的。

 二.问题

        我们先看spring编写的一套代码。

首先我们看一下项目结构:

        

分别是三层架构加resources层的配置文件。

Cotroller中注入service接口,serviceImpl中注入mapper接口,分别有对应的类实现对应的接口,完成从Controller层前端控制器到数据库操作层mapper的业务代码。

Controller层

@Controller("UserController")
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    @PostMapping("/add")
    public void addUser(){
        System.out.println("UserController中的addUser方法");
        userService.save();
    }
}

Service层

public interface UserService {
    public void save();
}
@Service("UserService")
public class UserServiceImpl implements UserService {
    @Autowired
    UserDao userDao;
    @Override
    public void save() {
        System.out.println("执行service中save方法");
        userDao.add();
    }
}

Dao层

public interface UserDao {
    public void add();
}
@Repository("UserDao")
public class UserDaoImpl implements UserDao {
    @Override
    public void add() {
        System.out.println("执行mybatis数据库操作");
        System.out.println("完成从controller到mapper层的依赖注入");
    }

}

配置文件applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <context:component-scan base-package="com.pxq"/>
</beans>

User实体类

@Data
@Component("user")
@Scope("singleton")
@ToString
public class User {
    private String id;
    private String name;
    private String password;
    private String email;
    public User(@Value("1") String id,
                @Value("张三")String name,
                @Value("123")String password,
                @Value("123@qq.com") String email) {
        this.id = id;
        this.name = name;
        this.password = password;
        this.email = email;
    }
}

还有最后的测试代码:

public class UserTest {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("applicationContext.xml");
        UserController userController = (UserController) context.getBean("UserController");
        userController.addUser();
    }
}

从上述代码看,1.传统spring,需要手写扫描包下所有组件并注册进容器。

<context:component-scan base-package="com.pxq"/>
@ComponentScan(basePackages = "com.pxq")

2.写测试代码需要读取配置文件中的内容,获得所有组件来使用对应的方法,测试代码繁琐,而且web项目难以测试。

3.需要手动配置很多依赖,且要考虑版本兼容问题。

三.优化

        1.对于第一个问题的优化。

先说结论:项目启动类所在层及其子层的所有组件都被扫入容器并注册,并加载需要的配置类。

@SpringBootApplication 
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

上述代码中起主要作用的是@SpringBootApplication注解

我们来看看它的内涵:

这个层级结构遵循yaml规则,同一层,级别相同。

@SpringBootApplication
    @SpringBootConfiguration
        @Configuration            //标注当前类为一个配置类
    @EnableAutoConfiguration
        @AutoConfigurationPackage
            @Import({AutoConfigurationPackages.Registrar.class}) 
            //获取启动类根目录,指定组件扫描器扫描的包位置
        @Import({AutoConfigurationImportSelector.class})
        //筛选出符合当前环境的自动配置类(根据pom文件中加入的依赖)
    @ComponextScan               
    //组件扫描器,扫描指定包下注解类文件,并作为spring容器使用

根据组合逻辑:

@Import({AutoConfigurationPackages.Registrar.class}) 
            //获取启动类根目录,指定组件扫描器扫描的包位置

@ComponextScan               
    //组件扫描器,扫描指定包下注解类文件,并作为spring容器使用

便可以完成对启动类下所有注解文件扫描和注册。

        还要提到的是:@ComponextScan  可以使用excludeFilters属性,过滤掉不需要加载的类

其中存在两个过滤类:TypeExcludeFilter和AutoCongigurationExcludeFilter。

TypeExcludeFilter会去BeanFactory中查找所有类型为TypeExcludeFilter的组件,并自定义过滤方法。

AutoCongigurationExcludeFilter用于过滤使用@Configuration和EnableAutoConfigure的类。

 2.关于测试方面的优化

        传统spring需要读取配置文件,来完成测试,而springboot项目可以在类中加上注解

@SpringBootTest(webEnvironment=springBootTest.WebEnvironment.***)

其中分为WebEnvironment.***的后缀有四种

MOCK:加载WebApplicationContext并模拟一个servlet环境,根据当前设置确定是否启动web环境

DEFINED_PORT:加载EmbeddedWebApplicationContext并提供真正的Servlet环境,使用自定义端口作为web服务器端口。

RANDOM_PORT:加载EmbeddedWebApplicationContext并提供真正的Servlet环境,使用随机端口作为web服务器端口。

NONE:加载ApplicationContext但不启动web环境。

@SpringBootTest(WebEnvironment=SpringBootTest.WebEnvironment.NONE)
public class MyTest(){
    @Autowired
    private UserService userService;

    public void Test(){
        userService.getById(1);
    }

}

将测试类当作组件,在组件中注入要用的组件,便可使用其方法完成测试。

web形式的测试就不写了,可以去查阅其他资料。

3.依赖配置的优化

        在springboot中如果想引入某个技术,只需使用springboot针对该技术的整合好的模块即可,这种模块称为starter,也叫启动器。

我们来看看最基础的依赖。

<!-- 最基础的启动器:所有功能的基石 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <version>2.7.0</version> <!-- 版本号可根据实际情况调整 -->
</dependency>

再往下看

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.7.0</version>
</dependency>

再往下看

<tomcat.version>9.0.63</tomcat.version> <!-- 默认嵌入式 Tomcat -->
<jetty.version>9.4.44.v20210927</jetty.version> <!-- 可选 Jetty 服务器 -->
<undertow.version>2.2.16.Final</undertow.version> <!-- 可选 Undertow 服务器 -->

<jackson.version>2.13.3</jackson.version> <!-- JSON 处理 -->
<mybatis.version>3.5.9</mybatis.version> <!-- MyBatis -->
<mybatis-spring.version>2.0.7</mybatis-spring.version>
<spring-data-commons.version>2.7.0</spring-data-commons.version> <!-- Spring Data 通用 -->
<spring-data-jpa.version>2.7.0</spring-data-jpa.version> <!-- JPA -->
<hibernate-core.version>5.6.10.Final</hibernate-core.version> <!-- JPA 实现 -->
<mysql-connector-java.version>8.0.29</mysql-connector-java.version> <!-- MySQL 驱动 -->

<spring-tx.version>${spring-framework.version}</spring-tx.version> <!-- 事务 -->
<spring-aop.version>${spring-framework.version}</spring-aop.version> <!-- AOP -->

<lombok.version>1.18.24</lombok.version> <!-- Lombok -->
<logback.version>1.2.11</logback.version> <!-- 日志实现 -->
<slf4j.version>1.7.36</slf4j.version> <!-- 日志门面 -->

这些还只是一部分,还有很多依赖的版本,还有一些关于spring等重要依赖未展示。

所以在最外层只需要在pom.xml中加入对应功能的启动器来调用对应功能,因为内部封装了对应的版本,无需手动写版本号,也避免了不兼容的问题。

基础型:

1.spring-boot-starter

2.spring-boot-starter-test

Web型:

1.spring-boot-starter-web

2.spring-boot-starter-webflux

不过多做展示了,可以去查阅相关启动器类型的资料帮助你更好理解。

至此关于我提出的三个问题我分别做出了解答。

四.关于后续

        springboot最核心的部分还没出现,我将结合之后的内容,通过自动配置结合对应功能来更清晰的表述出springboot对于spring的优化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值