后端开发框架Spring Boot快速入门

news2024/11/17 3:06:42

写在前面

推荐将本文与Spring Boot 相关知识和工具类一文结合起来看,本文为主,上面那篇文章为辅,一起食用,以达到最佳效果,当然,大佬随意。

IDEA创建Spring Boot工程

关于Spring Boot框架项目,IDEA为我们提供了比较快捷的创建方式,如下:

  1. 点击右上角的file,选择Project Structure,如下图:

捕获40.PNG

  1. 选择左侧的Modules,点击上面的加号,如下图:

捕获39.PNG

  1. 选择New Module

捕获38.PNG

  1. 左边一栏选择Spring Initializr,右边一栏配置项目相关属性,如下图:

捕获37.PNG

项目工程名,项目工程存储地址自定义,项目工程类型Type选择Maven,语言Language选择Java,后面三项建议不要改,直接默认即可,项目工程的软件开发工具包project SDK选择你自己安装的java JDK版本(我安装的是JDK 17),字段java 选择你自己安装的java JDK版本号,我这里选择的是17,包类型 Packaging选择Jar

5.点击Next后,选择该工程需要的依赖,这里我因为需要来开发Web应用,因此添加了Spring Web的依赖,又因为我选择了MySQL数据库来存储数据,因此我又添加了MySQL的依赖。

捕获38.PNG
捕获39.PNG

  1. 选好依赖后,点击Finish,整个Spring Boot项目创建就完成了。

Spring Boot整合Mybatis

SpringBoot的配置文件pom.xml中引入Mybatis的起步依赖

捕获34.PNG
引入好配置后,就可以正常使用Mybatis了。

Mybatis 前后端交互详解

图片1.png

如上图所示:

  • controller层是故意暴露出来的,里面是一些接口,用来与前端页面进行交互。
  • service层全是各种方法的接口,用来保护后端方法逻辑的具体实现,防止其源码泄露,该层作用类似于反向代理,每个接口都对应着一个具体方法的实现。
  • service层后面是implement逻辑层,它是整个系统的核心部分,用来与数据库进行交互,实现对应的所有后端逻辑,与前面的service层中的接口一一对应,保证程序的正常进行。
  • 再往后面走,就是dao层,即数据库,该层用于存放所有可以与数据库进行交互的方法接口,是十分重要的地方。
  • mapper层dao层中数据库方法接口的具体实现,与dao层方法接口一一对应。

前后端交互代码具体实现

项目的具体结构图:

image.png
OneSpringbootApplication 是启动类,运行该文件,整个项目就启动了

连接数据库:

捕获40.PNG
打开resource目录下的application.properties文件,在里面配置数据库相关信息,如上图红框所示。

  • spring.datasource.driver-class-name作用:设置JDBC驱动类的完全限定名。com.mysql.cj.jdbc.Driver 是MySQL Connector/J 8.0+的JDBC驱动类,它告诉Spring Boot应用程序要使用哪个类来加载和连接MySQL数据库。

  • spring.datasource.url作用:设置数据库连接的URL(即数据库所在路径),jdbc:mysql://localhost:3306/test233 表示数据库服务器运行在本地主机(localhost),使用3306端口,并且想要连接名为test233的数据库。

  • spring.datasource.usernamespring.datasource.password作用是用来记录数据库的用户名和密码。

  • mybatis.configuration.map-underscore-to-camel-case=true 作用是开启驼峰名与下划线命名之间的转换(驼峰命名eatFood,下划线命名eat_food)

  • 使用上述数据库配置前提是你已经将数据库驱动依赖添加到了项目的配置文件中(Maven的pom.xml)

controller 层:


//注解@RestController用于标记一个类,表明该类是一个
//控制器,并且其下的方法都将前端页面的返回数据作为响应
//(即处理前端页面的http请求)

@RestController
public class HelloController {

    //注解@RequestMapping用于将http请求和处理请求的控制器方法(类方法)
    //关联起来,建立映射关系,
    // 该注解有一个参数value,其作用就是设置请求路径,设置当客户端发送何种请求时,
    //下面的方法才会处理该请求
    
    //该注解的参数value是一个String类型的数组,也就是其中可以存放多个数据
    
    //当前端向"/hello"发出请求时,下面的函数就会接收到请求,
    //并自动调用来处理该请求
    @RequestMapping("/hello")
    public String hello() {
        return "hello world!";
    }


   
//@Autowired 注解用于将下面的对象(已经通过组件扫描注册到了IOC容器中)通过
//依赖注入 从IOC容器中注入到字段(这里字段是“userService”)中以供使用,
// 该对象必须被IOC容器视为一个Bean

    @Autowired
    private UserService userService;

    @RequestMapping("/findById")
    public book findById(Integer ID){
        return userService.findById(ID);
    }
}

service 层的项目结构:

image.png
service层的接口:


//该接口只是一个普通的接口,因此需要一个专门的类来实现这个接口中的方法
public interface UserService {
    public book findById(Integer ID);
}

service层的接口的具体实现(impl层):

//@Service注解用于标识一个类作为服务层组件
@Service
public class UserServiceImpl implements UserService {

    //IOC容器通俗解释就是一个负责管理对象生命周期和对象间关系的“大管家”,
    //具体来说,当我们需要某个对象时,我们不再直接在代码中创建它,而是告诉
    //IOC容器我们需要这个对象,容器会根据我们的请求和配置信息,自动创建对象,
    //并处理对象之间的依赖关系,以及一切与项目本身业务逻辑无关的东西
    //(这个对象在项目开始运行时就已经提前创建好了)
    
    // 我们想要使用直接从容器的取出即可,并且容器中已创建的对象可以被本项目其他
    //地方共享和使用,这种对象就是统称为Bean
    //一般被Spring框架提供的注解标注了的类,它们的对象都会被Spring容器视为Bean
    //(Spring容器就是IOC容器)
    //类本身不是Bean,类对应的实例才是Bean




    //@Autowired 注解用于将下面的对象(已经通过组件扫描注册到了IOC容器中)
    //通过依赖注入 从IOC容器中注入到字段(这里字段是“userMapper”)中以供使用,
    // 该对象必须被IOC容器视为一个Bean
    
    @Autowired
    private UserMapper userMapper;

    //当子类继承父类并重写父类的方法时,@Override注解可以帮助编译器检查该方法
    //是否确实重写了父类中的方法
    // 如果子类的方法名、参数列表和返回类型与父类中的方法不一致,那么编译器会
    //报错,提示重写失败,这有助于开发者及时发现并修正重写错误,避免运行时错误
    //的发生
    
    //简单来说,该注解作用就是表明其下面的方法为重写的方法
    @Override
    public book findById(Integer ID) {   
    //对UserService接口中的方法进行重写(即接口方法的具体实现)
        return userMapper.findById(ID);
    }
}

dao层与mapper层:

//@Mapper注解用于标识一个接口为MyBatis的Mapper接口
// 这样,MyBatis就能知道这个接口是专门用于操作数据库的,进而能够自动为这个
//接口创建一个代理实现类
// 这意味着你可以直接在应用程序中注入这个接口的实例,并调用它的方法来执行SQL语句,
//而不需要自己手动实现这个接口
// 即直接拿来使用,不需要再手动的去定义一个类来专门实现这个接口
@Mapper
public interface UserMapper {

    //@Select注解在MyBatis框架中用于直接在Mapper接口的方法上编写SQL查询语句,
    // 从而取代了传统的在XML映射文件中编写SQL语句的方式
    
    //@Select注解内部可以编写具体的SQL查询语句,用于从数据库中查询数据,
    //@Select注解下方的对应方法函数与上面SQL语句成映射关系
    //调用方法函数就会自动执行上面的SQL语句,并将SQL语句的结果作为该方法函数的
    //返回值进行return
    //在@Select注解的SQL语句中,可以使用占位符(如#{param})来绑定
    //下面方法中的参数
    @Select("select * from test233.book where ID=#{ID}")
    public book findById(Integer ID);
}

通过上面注解@Select@Mapper来将传统的Dao层Mapper层合在了一起。

实体类层—entity层:

image.png

public class book {

    private Integer ID;

    private String name;


    public book() {

    }

    public book(Integer ID,String name){
        this.ID=ID;
        this.name=name;
    }

    public Integer getID(){
        return this.ID;
    }

    public void setID(Integer ID){
        this.ID=ID;
    }

    public String getname(){
        return this.name;
    }

    public void setname(){
        this.name=name;
    }
}

该层的作用是用于存放一些实体类,这些实体类将会被用来接收数据库中对应表的数据,一个类对应一张表,表的字段就是类的成员变量,在前后端数据交互的过程中,这些实体类对象接收的数据会被系统自动转换成JSON数据格式。

常用注解

  • 注解@Component是一个通用注解,可以将标记的类实例作为Bean注入IOC容器中。
  • 注解@ComponentScan("包路径")用于组件扫描,扫描对应路径下的包当没有包路径时,默认扫描启动类同级的包和各自下面的子包。

组件扫描:如果遇见被Spring Boot提供的注解标记了的类,那么这些类的对象会被视为BeanSpringBoot会自动将这些类实例化并注入IOC容器之中,供应用程序在运行时使用,若存在组件未被扫描到,则系统不会创建组件当中的Bean实例,也不会创建该组件,与之相关联的其他Bean将会注入失败,与之相关联的功能组件将缺失。

  • 注解@Bean作用:将标记的方法的返回值交给IOC容器,成为IOC容器bean对象(当Spring容器启动时,它会查找@Configuration注解的类,并调用这些类中的@Bean注解的方法,将返回的实例注册为Bean,注入到IOC容器当中)。
  • 注解@RestController用于标记一个类,表明该类是一个控制器,并且其下的方法都将前端页面的返回数据作为响应(即处理前端页面的http请求)。
  • 注解@RequestMapping注解@PostMapping都是用于将http请求和处理请求的控制器方法(类方法)关联起来,建立映射关系,这两个注解都有一个参数value,其作用就是设置请求路径,设置当客户端发送何种请求时,下面的方法才会处理该请求,该注解的参数value是一个String类型的数组,也就是其中可以存放多个数据。
  • 注解:

Post 与 Requst 的区别:

  • Post 它要求被请求服务器要对它所提交的请求进行确认或者处理后才能给予响应,相对更加安全,效率也相对低点
  • Requst 它是更广泛地用于发送和接收数据,会将参数暴露在Url中,相对不安全,效率相对高点
  • 注解@Autowired 用于将其标记的对象(已经通过组件扫描注册到了IOC容器)通过依赖注入IOC容器中注入到字段(这里字段是“userService”)中以供使用。该对象必须被IOC容器视为一个Bean,因为只有这样才能保证IOC容器中拥有该对象。
  • 注解@Service用于标识一个类作为服务层组件。
  • 注解@Override可以帮助编译器检查该方法是否确实重写了父类中的方法。
  • 注解@Mapper用于标识一个接口为Mapper接口,这样,MyBatis就能知道这个接口是专门用于操作数据库的,进而能够自动为这个接口创建一个代理实现类,这意味着你可以直接在应用程序中注入这个接口的实例,并调用它的方法来执行SQL语句,而不需要自己手动实现这个接口;即直接拿来使用,不需要再手动的去定义一个类来专门实现这个接口
  • 注解@RestControllerAdvice 主要用于标注一个类来进行全局异常处理和全局数据绑定,该类中的方法会被同项目的其他程序自动调用,可以用于定义全局响应结果处理程序,确保应用程序返回给客户端的响应具有统一的格式和结构,总之,该注解作用就是标记其下面的类为一个全局的异常处理和所有数据预处理的"中央处理器"。
  • 注解@ExceptionHandler(异常类类名.class) 用来标注处理 异常类 的方法,此处的异常类可以是自定义的异常类,使用该注解可以捕获指定的异常,并按照自定义的方法处理该异常,一般与上面的注解配合使用
  • 注解@RequestBody用于将 HTTP 请求体中的数据绑定到对应的方法参数上。
 @PostMapping("/create")  
    public String create(@RequestBody MyObject myObject) {  
   // 在这里,myObject 已经被自动填充了请求体中的数据  
  // 你可以直接操作这个对象,而不需要手动解析请求体  
          
        // ... 处理 myObject 的逻辑 ...  
          
        return "Object created successfully";  
    }  
  • 注解@ResponseBody:用于标记一个方法的返回值应该被绑定到响应体。然而注解@RestController已经默认组合了注解@ResponseBody,也就是说注解@RestController标记的类下面的所有方法的返回值都会自动绑定到了响应体中。

在HTTP通信中,请求体(Request Body)和响应体(Response Body)是两个重要的概念,它们分别代表了HTTP请求和响应中携带的数据部分,里面可以携带的数据类型主要是JSON格式和表单数据

表单数据:当发送一个包含表单字段的HTTP POST请求时,请求体可能包含application/x-www-form-urlencoded类型的数据。这种格式将表单字段和值编码为键值对,并使用&符号分隔,将这些数据放在请求体当中,一同发送给服务器。

queryString格式数据就像是我们给网站地址“附加”一些额外的信息。比如,我们想在搜索引擎里搜索“苹果”,我们可能会输入http://search.com/?q=苹果。这里的?q=苹果就是queryString,它告诉我们搜索引擎要搜索的关键字是“苹果”。这种方式很适合传递少量、简单的信息。

  • 注解@CookieValue:用于绑定cookie值到方法参数。
@GetMapping("/cookie") 
public String cookie(
@CookieValue("JSESSIONID") String sessionId) { 
// ... 
}
//将cookie中的键JSESSIONID对应的值赋给sessionId
  • 注解@RequestHeader:用于绑定请求头到方法参数。
@GetMapping("/header") 
public String header(
@RequestHeader("User-Agent") String userAgent) { 
// ... 
}
//将请求头中的键User-Agent对应的值赋给userAgent
  • 注解@Validated 主要用于触发方法参数的校验,将它标记在类上,告诉系统该类中有方法需要进行参数校验。
  • 注解@Pattern 用于验证一个字符串是否符合指定的正则表达式(参数regexp存放指定的正则表达式),通常应用于类的字段、属性或方法的参数上,以确保输入的数据满足特定的格式要求。

image.png

  • 注解@NotNull该注解标记的变量的值不能为null。
  • 注解@NotEmpty该注解标记的变量的值不能为null,且如果是字符串的话,不能为空字符串。
  • 注解@Email该注解标记的变量必须满足邮箱格式

上面这三个注解是放在实体类中的,当实体类作为方法参数时,外部有注解@Validated标记且参数本身又是请求体的映射(@RequestBody)时,其内部的注解才会生效(这只对实体类内部Validation依赖相关的注解有效)。

捕获28.PNG

  • 注解@URL 用来判断其标记的参数是否是一个合法的url地址。

捕获36.PNG

  • 注解@Test 用于标记一个方法是测试方法,这样测试框架就能自动识别并运行它。
  • 注解@JsonIgnore,该注解标记的成员变量,当系统将数据转换成JSON格式时,将会忽略掉该成员变量的值(保护密码不被泄露)
  • 注解@JsonFormat(pattern = "yyyy-MM-dd HH-mm-ss") 用来指定存放时间的字段的时间输出的格式(年-月-日 时-分-秒)

数据库相关注解MyBatis框架中用于直接在Mapper接口的方法上编写SQL语句,从而取代了传统的在XML映射文件中编写SQL语句的方式,这些数据库相关注解,其内部可以编写具体的SQL查询语句,用于从数据库中增删查改数据,数据库相关注解下方的对应方法函数与上面SQL语句成映射关系,调用方法函数就会自动执行上面的SQL语句,并将SQL语句的结果作为该方法函数的返回值进行return,在数据库相关注解的SQL语句中,可以使用占位符(如#{param})来绑定标记的方法中的参数。

数据库相关注解有:

  • 注解@Select用于标注查询语句
  • 注解@Insert用于标注插入语句
  • 注解@Update用于标注更新语句
  • 注解@Delete用于标注删除语句

传统xml文件映射(配置动态的SQL语句)

Mapper接口层,可以直接使用注解来将SQL语句映射绑定到对应方法上,如下:


@Mapper
public interface CategoryMapper {

    //新增文章分类
    @Insert("insert into big_event.category(category_name, category_alias, create_user, create_time, update_time) " +
            "value(#{category.categoryName},#{category.categoryAlias},#{category.createUser},now(),now())")
    public void addCategory(Category category);


    //通过文章的分类名查找分类
    @Select("select * from big_event.category where category_name=#{categoryName}")
    public Category findByCategoryName(String categoryName);

    //通过文章的分类ID查找分类
    @Select("select * from big_event.category where id=#{id}")
    public Category findById(Integer id);

    //通过用户ID获得其创建的所有分类
    @Select("select * from big_event.category where create_user=#{userId}")
    public List<Category> findByCreateUser(Integer userId);
 }

但是,上面却无法映射绑定动态的SQL语句到对应方法上,要想映射动态的sql语句,就只要采用传统的数据库映射方式----xml文件映射

xml映射文件要求

xml配置文件必须放在resources 目录下,在该目录下,它的路径必须与Mapper层接口所在路径一致。

例如Mapper层接口路径:com.example.two_project.mapper,那么对应的xml文件路径就必须是resources/com/example/two_project/mapper

xml文件配置动态SQL语句

<?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.example.two_project.mapper.ArticleMapper">
<!-- namespace 必须是对应的Mapper层接口的全类名   -->
 
    
    <select id="list" resultType="com.example.two_project.entity.Article">
        select * from big_event.article
        <where>
            <if test="state!=null">
                state=#{state}
            </if>

            <if test="categoryId">
                and category_id=#{categoryId}
            </if>

            and create_user=#{id}
        </where>
    </select>

</mapper>

<select> 标签就表示Select语句,属性id为该条SQL语句对应的函数的函数名,
属性resultType为数据库查询结果的每一条数据的返回类型(即该表对应的实体类的全类名)

<where> 标签就是SQL语句中的where,与一般的where相比,它的区别是它可以通过if的判断来动态地改变查询条件

<if> 标签中的test参数为判断条件,如果条件满足,则将标签内的语句加入where当中且若这是where中的第一个条件,
那么该条件前面的and将会被省略,若不满足,则不将标签内的语句加入.

文件对应的映射方法中的参数可以直接在标签中使用

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="">

Spring Boot 配置文件

配置文件的格式

Spring Boot的配置文件有两种格式,分别是.properties.yaml/yml,两种配置文件的作用并没有什么区别,只是写法上有所不同:

捕获1.PNG

在企业级开发中,更加常用的是.yml格式的文件

捕获2.PNG

书写配置信息

不只是.yml格式的配置文件,.properties格式也是一样的,它们都可以用来书写第三方技术配置信息也可以来书写自定义的配置信息;当书写自定义配置信息时,如下图:

捕获3.PNG

将程序中的一些静态属性放在一起,写成一个配置文件,这样当属性发生变化时就不用改代码,只需要修改配置文件,然后重启服务器即可。
捕获4.PNG
如上图所示,是书写.yml配置文件的一些要求。

捕获5.PNG
如上图中的属性"hobbies",表示该属性是一个数组类型,格式: "-"+" "+数组中的元素

获取配置信息

当属性写入属性文件后,在代码中,我们该如何获取这些属性呢?

捕获6.PNG
如上图所示,通过注解@Value("{键名}")来获得对应的属性,该注解下面的变量就是用来接收对应属性(键)的值的。但是如果属性过多,又不想给每一个变量都写注解,则可以采用下面这种方法:

捕获7.PNG

如上图,在对应的类上面加注解@ConfigurationProperties(prefix="前缀")(这里的前缀也是在配置文件中由用户自定义的),当使用了该注解后,其类下面对应的成员变量名必须与配置文件中同一前缀的属性名相同且一一对应。

Bean 注册

第三方若想注册为Bean(即被SpringBoot自动创建实例并注入IOC容器),只靠在对应类上添加一般的注解是不行的,这里就需要特殊的注解了。

第三方注册为Bean方式一

方式一,在启动类中添加方法,并在该方法上面添加注解@Bean,如下图:

捕获21.PNG

@Bean注解作用:将标记的方法的返回值交给IOC容器,成为IOC容器bean对象(当Spring容器启动时,它会查找@Configuration注解的类,并调用这些类中的@Bean注解的方法,将返回的实例注册为Bean)

也可以单独开一个配置类(注解@configuration标记的类)的文件,将所有想注册为Bean的第三方集中处理,如下图:

捕获22.PNG

如果在注解@Bean标记的方法中想使用在IOC容器中已经注册的Bean对象,那么只需要在方法上声明即可,spring会自动的注入,如下图(country是已经在IOC容器中注册好的Bean对象)。

image.png

第三方注册为Bean方式二

方式二, 通过注解@Import将对应的第三方类引入,Spring容器会自动将其类的对象注册为Bean,注入IOC容器中。

  • 引入格式:@Import(xxx.class)
  • 引入位置:整个项目的启动文件当中。

捕获24.PNG

@Import(类名.class),其中引入的这个类可以普通类,也可以是配置类(@configuration标记了的类),或者是ImportSelector接口实现类

ImportSelector接口实现类:
image.png
如上图所示,我们首先要实现ImportSelector这个接口,重写其中的 selectImports()方法(该方法是自动调用的),返回值返回一个字符串类型的数组,该数组中的每一个字符串都是用户需要注册为Bean对象的类的地址(全类名)。然后注解@Import只需要引入这个接口实现类的类名即可,这样就避免了因引入的类太多,导致代码不美观的问题。

在一般开发中,ImportSelector接口实现类的方法的返回值的这个字符串数组一般不是写死的,而是从配置文件中读出来的

Resources/META-INF/spring/ 目录下,创建后缀名.imports的配置文件,里面书写上所有自定义的需要注册为Bean的类的地址(全类名),一个类占一行。

读取配置文件中的信息,示例如下图:

捕获29.PNG
捕获30.PNG
如图,imports是设置的一个字符串列表,用于存放配置文件中的各个类的全类名;is 是获取到的输入流,后面的 “common.imports” 是配置文件名,整行代码的作用就是将配置文件中的数据转换成输入流存入变量is,下面的变量br是对输入流的一个封装,将其封装成一个缓冲字符流。while循环是用来按照每一行来读取缓冲字符流当中的数据,并用字符串变量line来接收,将每一行数据添加至字符串列表imports当中,所有数据读取完毕后,要关闭缓冲字符流br;最后,将字符串列表转换成字符串数组返回回去。

自定义组合注解

捕获31.PNG
如上图所示,选择Annotation,创建自定义的组合注解

捕获32.PNG
如上图所示,上面两个注解都是必不可少的。第一个是表明该自定义注解可以在类上使用,第二个表明该自定义注解在系统运行期间,一直存在。除了这两个注解,其他的均可以自定义。若要使用这个注解,就像普通注解一样直接使用即可,注解名为创建的组合注解的文件名。常用于实现下图第三条:

捕获33.PNG

Bean 的注册条件

用户可以通过注解@Conditional的衍生注解来设置对象注册为Bean的条件,常用的注解如下图所示。

image.png

在配置类中,注解@Bean所标记的方法,其返回值会被注册为Bean,我当然可以提前为要注册为Bean的对象赋值,如下图,在方法的参数上通过注解@Value("${键名}")来确保每个参数被传入指定的值。注解@ConditionalOnProperty(prefix="前缀",name={"键名1","键名2"}) 来判断配置文件中是否存在对应属性,若不存在,则其下面整个方法的返回值将不再被注册为Bean。

image.png
注解@ConditionalOnMissingBean(类名.class),如下图所示,如果IOC容器中不存在Country类的Bean对象,则执行下面的方法,注入Province,否则不注入。

image.png

注解@ConditionalOnClass(name="类的完整路径名"),如下图所示,如果当前配置环境存在指定的类,则执行下面的方法,注入Province,否则不注入。
image.png

自动配置的原理

自动配置就是在SpringBoot程序启动后,起步依赖中的一些Bean对象会自动注入到IOC容器之中。

原理:jar包内定义了一些类,目的是想要这些类的实例作为Bean注入到IOC容器中,即自动注入;首先定义一个配置类,配置类中用注解@Bean来标记方法,通过这些方法,SpringBoot会将它们返回的实例作为Bean注入到IOC容器中,再定义一个自动配置类,加上两个注解@import(配置类类名.class)@AutoConfiguration;前者引入了配置类,保证其在不同级目录下也可以使用,后者标识这是一个自动配置类。最后在项目的resources目录下的META-INF目录下的spring目录下再定义一个后缀名为.imports的文件,在文件中加入该自动配置类的全类名;当系统启动时,系统会在该目录下(“/resources/META-INF/spring/xxx.imports”)的配置文件中找是否有自动配置类(注解@AutoConfiguration标记的类),有就自动调用实例化该类。实例化该类,会导致系统通过@import访问到配置类,配置类中的方法会被自动调用,这样就自动配置就搞定了。

@Configuration@AutoConfiguration注解的区别:

1. @Configuration 必须通过组件扫描,才能自动配置Bean,若不在启动类的同级目录或子目录下,则需要@ComponentScan("路径")来专门指定扫描。

  1. @AutoConfiguration 会被加载执行两次,一次是由@ComponentScan(如果配置了的话),另一次是由自动配置机制,也就是说只要该类在该项目下,且配置文件.imports 里有该类的全类名,该类就会被系统自动调用,自动配置Bean。
  2. @Configuration@AutoConfiguration注解一般配合使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1571503.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Win10 下 Vision Mamba(Vim-main)的环境配置(libcuda.so文件无法找到,windows系统运行失败)

目录 1、下载NVIDIA 驱动程序、cuda11.8、cudnn8.6.0 2、在Anaconda中创建环境并激活 3、下载gpu版本的torch 4、配置环境所需要的包 5、安装causal_conv1d和mamba-1p1p1 安装causal_conv1d 安装mamba-1p1p1 6、运行main.py失败 请直接拉到最后查看运行失败的原因&am…

虚幻UE5数字孪生蓝图开发教程

一、背景 这几年&#xff0c;智慧城市/智慧交通/智慧水利等飞速发展&#xff0c;骑士特意为大家做了一个这块的学习路线。 二、这是学习大纲 1.给虚幻UE5初学者准备的智慧城市/数字孪生蓝图开发教程 https://www.bilibili.com/video/BV1894y1u78G 2.UE5数字孪生蓝图开发教学…

【stm32】I2C通信协议

【stm32】I2C通信协议 概念及原理 如果我们想要读写寄存器来控制硬件电路&#xff0c;就至少需要定义两个字节数据 一个字节是我们要读写哪个寄存器&#xff0c;也就是指定寄存器的地址 另一个字节就是这个地址下存储寄存器的内容 写入内容就是控制电路&#xff0c;读出内容就…

Arcgis Pro地理配准

目录 一、目的 二、配准 1、找到配准工具 2、添加控制点 3、选择控制点 4、添加更多控制点 5、配准完成、保存 三、附录 1、查看控制点或删除控制点 2、效果不好怎么办 一、目的 下面我们将两张地图进行配准&#xff0c;其中一张有地理位置&#xff0c;而另外一张没…

​​​​​​​【人工智能】手写数字识别

手写数字识别 实验背景 数据集介绍 MNIST数据集包含了一系列的手写数字图像&#xff0c;包括0到9的数字。每张图像都是灰度图像&#xff0c;尺寸为28x28像素。数据集共包含60000张训练图像和10000张测试图像。 MNIST数据集的目标是通过训练一个模型&#xff0c;使其能够正确地识…

NPW(监控片的)的要点精讲

半导体的生产过程已经历经数十年的发展&#xff0c;其中主要有两个大的发展趋势&#xff0c;第一&#xff0c;晶圆尺寸越做越大&#xff0c;到目前已有超过70%的产能是12寸晶圆&#xff0c;不过18寸晶圆产业链推进缓慢&#xff1b;第二&#xff0c;电子器件的关键尺寸越做越小&…

LCD屏幕mmap显示

目录 前言 一.LCD显示 二.LCD颜色显示 2.1 直接显示 2.2 mmap映射显示 前言 mmap是一种内存映射文件的方法&#xff0c;它允许将文件或其它对象映射到进程的地址空间。 使用mmap映射函数进行映射显示&#xff0c;与屏幕普通直接显示相比有很大的优势 一.LCD显示基础 像素、分辨…

mac 切换 jdk

查看 mac 上都有哪些版本 /usr/libexec/java_home -V看准版本切换 按前缀切换 比如 export JAVA_HOME/usr/libexec/java_home -v 1.8这样会随机一个 1.8 的 如果想再确定一个比如 openjdk export JAVA_HOME/usr/libexec/java_home -v 1.8.0_292这个方式是临时的&#xff0c…

图像处理入门 3(how to get the pixel pitch / 如何获得单个像素的尺寸)

在这里一节里面&#xff0c;将记录如何获得一个相机传感器中单个像素点的尺寸&#xff0c;为了实现不同相机照片之间的匹配。 如果我们知道了相机传感器的尺寸和分辨率的大小&#xff0c;自然就可以求出单个像素的大小。 在这里插入图片描述&#xff1a; 如何获得相机传感器的…

vue创建项目下载动态路由v-for mounted websocket :style :class store使用说明

在Vue中创建一个项目&#xff0c;并整合动态路由、v-for、mounted生命周期钩子、WebSocket、:style、:class以及Vuex的store&#xff0c;涉及到多个Vue核心特性的使用。下面我将简要说明如何逐步整合这些特性。 1. 创建Vue项目 使用Vue CLI创建项目&#xff1a; 2. 配置动态路…

[蓝桥杯 2017 国 C] 合根植物

[蓝桥杯 2017 国 C] 合根植物 题目描述 w 星球的一个种植园&#xff0c;被分成 m n m \times n mn 个小格子&#xff08;东西方向 m m m 行&#xff0c;南北方向 n n n 列&#xff09;。每个格子里种了一株合根植物。 这种植物有个特点&#xff0c;它的根可能会沿着南北…

spark-hive连接操作流程、踩坑及解决方法

文章目录 1 简介2 版本匹配3 spark hive支持版本源码编译3.1 spark-src下载3.2 maven换源3.3 spark编译 4 hive 安装与mysql-metastore配置4.1 mysql下载安装4.1.1 为mysql设置系统环境变量4.1.2 初次登陆更改root身份密码4.1.3 安装后直接更改密码 4.2 hive初始化4.2.1 编写hi…

Ps:色调均化

色调均化 Equalize命令通过均匀分布图像的亮度值来优化图像的对比度&#xff0c;使得图像色调更加平衡。 Ps菜单&#xff1a;图像/调整/色调均化 Adjustments/Equalize “色调均化”只有调整命令&#xff0c;无调整图层&#xff0c;无选区时无操作选项。 色调均化命令将重新映射…

hbuilderX创建的uniapp项目转移到vscode

场景&#xff1a;一直使用hbuilderX开发的朋友想转移到vscode获取更好的TypeScript支持&#xff0c;所以想把整个项目目录拖到vscode进行开发&#xff0c;但发现运行不了&#xff0c;提示没有package.json等&#xff0c;并且不能执行pnpm命令 首先&#xff0c;我们先来看一下h…

LeetCode刷题实战1:两数之和

从今天开始加入刷题大军&#xff0c;把算法题刷爆&#xff0c;我们直接进入主题。 题目内容 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应…

zdpreact_antdesginpro 研究一下react里面比较流行的一个UI框架,开发后台管理系统

首先看一下最开始的代码&#xff1a; 这里面大部分的东西都可以删掉&#xff0c;比如README&#xff0c;只留下中文的那个就可以了。 之后看看README.md中介绍的特性。 特性 &#x1f4a1; TypeScript: 应用程序级 JavaScript 的语言&#x1f4dc; 区块: 通过区块模板快速…

canvas画图,画矩形、圆形、直线可拖拽移动,可拖拽更改尺寸大小

提示&#xff1a;canvas画图&#xff0c;画矩形&#xff0c;圆形&#xff0c;直线&#xff0c;曲线可拖拽移动 文章目录 前言一、画矩形&#xff0c;圆形&#xff0c;直线&#xff0c;曲线可拖拽移动总结 前言 一、画矩形&#xff0c;圆形&#xff0c;直线&#xff0c;曲线可拖…

2024最新在线工具箱/ 站长IT工具箱/网站系统源码下载

2024最新在线工具箱/ 站长IT工具箱/网站系统源码下载- 更多详情及下载地址请访问https://a5.org.cn/a5_ziyuan/39525.html 转载请注明出处!

Android Studio gradle-8.4 配置 GreenDao

1.配置项目下的build buildscript {repositories {mavenCentral()}dependencies {classpath ("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0")classpath ("org.greenrobot:greendao-gradle-plugin:3.3.1") // 使用最新版本} } 2.配置app下的build i…

泰坦尼克号幸存者数据分析

泰坦尼克号幸存者数据分析 1、泰坦尼克号数据集2、数据集加载与概览3、泰坦尼克号幸存者数据分析4、哪些人可能成为幸存者&#xff1f; 1、泰坦尼克号数据集 泰坦尼克号的沉没是世界上最严重的海难事故之一&#xff0c;造成了大量的人员伤亡。这是一艘号称当时世界上最大的邮轮…