Springboot 核心注解和基本配置解读

目录

 

1. Springboot 入门与原理

1.1 Springboot 简介

1.1.1 什么是Springboot

1.1.2 Springboot 主要优点

1.2 Springboot 相关注解

1.2.1 元注解

 1.2.1.1 @Target

1.2.1.2 @Retention

1.2.2 @Configuration

1.2.3 @Import

1.2.3.1 直接注入

1.2.3.2 实现 ImportSelector 注入

1.2.3.3 实现 ImportBeanDefinitionRegistrar 接口 注入

1.2.4 @Conditional

1.2.5 @ImportResource和@ConfigurationProperties

1.2.6 @PropertySource+@Value

1.2.7 @SpringBootApplication


 

1. Springboot 入门与原理

1.1 Springboot 简介

1.1.1 什么是Springboot

开发一个web应用,从最初开始接触Servlet结合Tomcat, 跑出一个HelloWolrld程序,是要经历特别多的步骤; 后来就用了框架Struts,再后来是SpringMVC,到了现在的SpringBoot,SpringBoot就是一个JavaWeb的开发框架,和SpringMVC类似,对比其他
JavaWeb框架的好处,官方说是简化开发,约定大于配置, 能迅速的开发web应用,几行代码开发一个http接口。

所有的技术框架的发展似乎都遵循了一条主线规律:从一个复杂应用场景衍生 一种规范框架,人们只需要进行各种配置而不需要自己去实现它,这时候强大的配置功能成了优点;发展到一定程度之后,人们根据实际生产应用情况,选取其中实用功能和设计精华,重构出一些轻量级的框架;之后为了提高开发效率,嫌弃原先的各类配置过于麻烦,于是开始提倡“约定大于配置”,进而衍生出一些一站式的解决方案。


随着 Spring 不断的发展,涉及的领域越来越多,项目整合开发需要配合各种各样的文件,慢慢变得不那么易用简单,违背了最初的理念,甚至人称配置地狱。Spring Boot 正是在这样的一个背景下被抽象出来的开发框架,目的为了让大家更容易的使用 Spring 、更容易的集成各种常用的中间件、开源软件。

Spring Boot 基于 Spring 开发,Spirng Boot 本身并不提供 Spring 框架的核心特性以及扩展功能,只是用于快速、敏捷地开发新一代基于 Spring 框架的应用程序。也就是说,它并不是用来替代 Spring 的解决方案,而是和 Spring 框架紧密结合用于提升 Spring 开发者体验的工具。Spring Boot 以约定大于配置的核心思想,默认帮我们进行了很多设置,多数 Spring Boot 应用只需要很少的 Spring 配置。同时它集成了大量常用的第三方库配置(例如 Redis、MongoDB、Jpa、RabbitMQ、Quartz 等等),SpringBoot 应用中这些第三方库几乎可以零配置的开箱即用。

简单来说就是SpringBoot其实不是什么新的框架,它默认配置了很多框架的使用方式,就像maven整合了所有的jar包,spring boot整合了所有的框架 。

1.1.2 Springboot 主要优点

  • 为所有Spring开发者更快的入门
  • 开箱即用,提供各种默认配置来简化项目配置
  • 内嵌式容器简化Web项目
  • 没有冗余代码生成和XML配置的要求

 

1.2 Springboot 相关注解

1.2.1 元注解

Java元注解是包括: @Retention、@Target、@Documented、@Inherited等。如下图:

f359b3b6696246a6b46448cab0f4254a.png

 1.2.1.1 @Target

@Target用于指定注解的作用范围,它的取值包括:

e7d30403b46b4bd5a34ab31b35ec05e5.png
 

1.2.1.2 @Retention

@Retention用于指定注解的生命周期,它的取值包括:

61632a7d71ee4c408bfad26810709d32.png

 

1.2.2 @Configuration

添加了 @Configuration 的类是 SpringBoot 的配置类,这个配置类等价于 Spring 的 beans.xml 配置文件;在配置类中可以使用 @Bean 注解定义 Bean 对象。配置类中调用 Bean 对象定义方法可得到对应 Bean 对象,即使多次调用,返回的是同一个对象。

@Configuration
public class MyConfiguration {
    @Bean
    public User user(){
        return new User();
    }
}

进入 @Configuration 注解,发现该注解除了 value 属性,还有一个 proxyBeanMethods 属性,且默认值为 true。该配置表示添加了 @Configuration 的配置类中的所有方法都是代理对象方法,代理对象调用 方法,SpringBoot 总会检查 该方法返回的 User 对象在容器中是否已经存在,如果存在就直接返回容器中的 Bean 对象。代码如下:打印结果一直为true。

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);
        MyConfiguration myconfiguration = run.getBean("myConfiguration", MyConfiguration.class);
        System.out.println(myconfiguration.user()==myconfiguration.user());
    }
}

1.2.3 @Import

@Import是可以通过配置来控制是否注入该Bean,也可以通过条件来控制注入哪些Bean到Spring容器中。

1.2.3.1 直接注入

在@Configuration标注的类上使用@Import引入了一个类后,就会把该类注入容器中。类似于@Service,@Component等注解。代码如下:

@Configuration
@Import({User.class})
public class MyConfiguration {

}

1.2.3.2 实现 ImportSelector 注入

通过ImportSelector的使用通过开关来控制注入哪些Bean,来实现动态的Bean对象的注入。

设置接口:

public interface FatherInterface {
    void test();
}

设置接口实现类:

public class A implements FatherInterface{
    @Override
    public void test() {
        System.out.println("执行了A");
    }
}
public class B implements FatherInterface {
    @Override
    public void test() {
        System.out.println("执行了B");
    }
}

定义ImportSelector实现类

public class MySelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(Switch.class.getName());
//获取目标元素上某注解的属性值
        String value = (String) annotationAttributes.get("value");
        if(value.equals("A"))
            //将A类Bean对象注入Spring容器
            return new String[]{A.class.getName()};
        else
            //将B类Bean对象注入Spring容器
            return new String[]{B.class.getName()};

    }
}

定义Switch注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(MySelector.class)
public @interface Switch {
    String value() default "";
}

测试代码如下

@SpringBootApplication
@Switch(value = "A")
public class DemoApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);
        A bean1 = run.getBean(A.class);
        System.out.println(bean1);
        B bean2 = run.getBean(B.class);
        System.out.println(bean2);

    }
}

测试结果如下:

5db9e2d52d6f47f884120bc125c9df8f.png
 

 将value值改为字符串B,然后就会在Spring容器中可以获得B类Bean对象,获得不了A类Bean对象,然后我们就可以进行动态的添加Bean对象。

1.2.3.3 实现 ImportBeanDefinitionRegistrar 接口 注入

当配置类实现了ImportBeanDefinitionRegistrar 接口,你就可以自定义往容器中注册想注入的Bean。

这个接口相比与 ImportSelector 接口的主要区别就是,ImportSelector接口是返回一个类,你不能对这个类进行任何操作,但是ImportBeanDefinitionRegistrar 是可以自己注入 BeanDefinition,可以添加属性之类的。

 

通过实现ImportBeanDefinitionRegistrar的方式来完成注入。

public class MyBeanRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).addPropertyValue("username", "admin")
                .addPropertyValue("password", "132")
                .getBeanDefinition();
        registry.registerBeanDefinition("myuser",beanDefinition);
    }
}

测试代码

@SpringBootApplication
@Import(MyBeanRegistrar.class)
public class DemoApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);
        User myuser = run.getBean("myuser", User.class);
        System.out.println(myuser);

    }
}

1.2.4 @Conditional

@Conditional 注解是用来匹配只有满足所有指定条件才能将Bean注册到Spring上下文中。例如:当某jar包在类路径下,自动配置一个或多个bean,这就是根据特定条件控制Bean的创建行为,这样就可以利用这个特性进行一些自动配置。

如下图:

a47d62258c7f44ddadcd41a9ed06cf82.jpeg

 除此之外我们还可以自定义条件控制Bean对象的创建。代码如下:

自定义MyConditon类

public class MyCondition implements Condition {
    
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        //此处编写业务逻辑
        return true;
    }
//true为通过,false为不通过不能创建bean
}


Configuration类代码

@Configuration

//@ConditionalOnMissingBean(name = "hello")
//@EnableConfigurationProperties(User.class)
public class MyConfiguration {

    @Bean
    @Conditional(MyCondition.class)
    public User user(){
        return new User();
    }

}

1.2.5 @ImportResource和@ConfigurationProperties

@ImportResource主要用于原生配置文件引入。SpringBoot是全注解开发,对于一些使用配置文件项目,SpringBoot可以通过@ImportResource将配置文件中的内容引入SpringBoot项目中,不需要将配置文件中的内容一个一个的按照注解的方式改动。主要用于使用xml文件向容器装配组件。这部分本作者用的不多,代码故在此省略。

 

有时候有这样子的情景,我们想把配置文件的信息,读取并自动封装成实体类,这样子,我们在代码里面使用就轻松方便多了,这时候,我们就可以使用@ConfigurationProperties,它可以把同类的配置信息自动封装成实体类,主要用于Bean对象的属性注入。

在application.yml文件中配置如下:

user:
  username: admin
  password: 123

自定义User类

@Component
@ConfigurationProperties(prefix = "user")
public class User {
    private String username;
    private String password;

}

这里必须要加@Component组件,因为只有Spring容器中的Bean对象才能使用Springboot的强大功能。这里也可以不加@Component组件,在Configuration中添加如下:

@Configuration
@EnableConfigurationProperties(User.class)
public class MyConfiguration {
}

1.2.6 @PropertySource+@Value

SpringBoot默认能够读取resources目录下的application配置文件,当我们的配置文件不在全局配置文件中,该如何使用呢?
@PropertySource+@Value可以读取其它配置文件内容。

新建test.yml,内容如下:

user:
  username: admin

自定义MyUser类读取配置文件内容

@Component
@PropertySource({"test.yml"})
public class MyUser {
    @Value("${user.username}")
    public String username;
}

1.2.7 @SpringBootApplication

run函数传入的当前启动类的字节码,最重要的是传入了@SpringBootApplication,点开它,就能发现它是一个复合注解,有多个注解组成,如下图:

62bce9d304e24c7c954faaf979af0645.png

 

@SpringBootConfiguration

该注解源码,会发现本质是@Configuration,定义该类是个配置类,功能等同于xml配置文件。@Configuration和@Bean,两个注解合作创建一个简单的Spring配置类,可以用来代替响应的xml配置文件可以理解为创建了IOC容器了。如下图:

3eb817191f4c4190a22a85e56ecb2649.png

 

@ComponentScan

这个注解对应的是Spring的XML配置中的ComponentScan,也就是自动扫描并加载符合条件的组件,将他们加载到IOC容器中。也可以通过basePackages等属性来细粒度的定制@ComponentScan自动扫描的范围,默认扫描引导类所在的包以及子包。

 

@EnableAutoConfiguration

点开源码发现本质是@Import如下图:

b61faf9c89954cab91a7f7fe73e01dab.png

  • @EnableAutoConfiguration也是借助@Import的帮助,将所有符合自动配置条件的bean定义加载到IOC容器。@EnbaleAutoConfiguration会根据类路径中的jar依赖为项目进行自动配置,如:添加了spring-boot-starter-web,就会自动添加Tomcat和SpringMVC的依赖,springboot会对Tomcat和SpringMVC进行自动配置。
  • springboot是如何完成自动配置的呢?
    • 启动类的run方法执行,传入SpringBootApplication注解的字节码
    • 这个注解是个复合注解,其中有一个EnableAutoConfiguration
    • 这个EnableAutoConfiguration中又有一个Import注解,这个注解可以用来导入其他类
    • 通过这个Import,导入的是AutoConfigurationImportSelector,这个类内部有一个方法selectImports。这个方法会扫描所有jar包下的spring.factories文件,解析其中的配置(key=value的键值对形式),创建对应的类到Spring容器中。

总结

在Springboot程序运行的时候:
1.SpringBoot先加载所有的自动配置类xxAutoConfiguration
2.每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值。从xxProperties里面拿。xxProperties和配置文件进行了绑定。
3.生效的配置类就会给容器中装配很多组件。
4.只要容器中有这些组件,相当于这些功能就有了。
5.我们可以定制化配置
   1.用户直接自己@Bean替换底层的组件。
   2.用户去看这个组件是获取的配置文件什么值就去修改。在application全局配置文件中进行修改。

这就是Springboot中的约定大于配置。

至此本篇文章到此结束。

02598cb098ab45b6ae6e4b9758a6913c.gif

 

 

 

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Error: Cannot find module ‘webpack‘ 问题解决办法

这句话的意思是&#xff1a;没有找到webpack模块。 就算之前你装了webpack&#xff0c;那肯定是非全局安装 所以要全局安装 npm install --save-dev webpack 问题解决

4.蜂鸣器

1.了解蜂鸣器&#xff1a; 蜂鸣器在使用3.3V无法驱动&#xff0c;需要借助到三极管的放大特性(IcβIb)将蜂鸣器驱动&#xff1b;本次原理图中&#xff0c;接R33电阻是因为当STM32单片机复位时处于浮空状态&#xff0c;防止小电流让蜂鸣器响而添加的。 2.蜂鸣器原理图&#xf…

剖析Linux文件系统

Linux 文件系统体系结构是一个对复杂系统进行抽象化的有趣例子。通过使用一组通用的 API 函数&#xff0c;Linux 可以在许多种存储设备上支持许多种文件系统。例如&#xff0c;read 函数调用可以从指定的文件描述符读取一定数量的字节。read 函数不了解文件系统的类型&#xff…

Java——《面试题——Redis篇》

前文 java——《面试题——基础篇》 Java——《面试题——JVM篇》 Java——《面试题——多线程&并发篇》 Java——《面试题——Spring篇》 Java——《面试题——SpringBoot篇》 Java——《面试题——MySQL篇》​​​​​​ Java——《面试题——SpringCloud》 Java…

使用Nginx的反向代理来访问服务器例子——Nginx笔记

因为网站上的视频加载过慢&#xff0c;想使用nginx服务器实现HLS视频播放服务。顺便记录一下通过Nginx的方向代理来访问服务器。这里在原先的项目上进行改造。原先的项目已经部署在公网&#xff0c;使用tomcat服务器&#xff0c;可以直接用地址进行访问。 1.这里使用的8080端口…

阿里飞猪三面

&#xff08;有许多人是用青春的幸福作成功的代价的。——莫扎特&#xff09; 背景 该岗位是阿里飞猪的前端部门&#xff0c;岗位名称是node.js高级/专家开发工程师。主要负责用NodeJs作为后端技术&#xff0c;向上层Java&#xff0c;Node等业务服务&#xff0c;提供中间层基础…

ChatGPT对未来编程语言发展的影响与展望

目录 一、引言1.ChatGPT的介绍与背景介绍背景 2.编程语言发展的重要性和挑战重要性挑战 二、ChatGPT在编程领域的应用1.自然语言处理技术在编程中的应用现状2. ChatGPT作为编程辅助工具的潜力与优势 三、ChatGPT对编程语言发展的影响1. 创新编程模式的涌现2. 语言设计与交互方式…

【问题记录】如何使用 pip 在 linux 上安装 pytorch

一、进入 pytorch 官网 pytorch 官网&#xff1a;https://pytorch.org/ 二、在页面选择环境 三、复制官网弹出的命令并运行即可 pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118

Redis中的缓存雪崩、击穿、穿透的原因以及解决办法

缓存雪崩、击穿、穿透一旦发生&#xff0c;会导致大量的请求积压到数据库层。如果请求的并发量很大&#xff0c;就会导致数据库宕机或是故障&#xff0c;这就是很严重的生产事故了。 俗话说&#xff0c;知己知彼&#xff0c;百战不殆。了解了问题的成因&#xff0c;我们就能够…

微服务_Nacos

简介 Nacos&#xff08;全称为“动态服务发现、配置和服务管理平台”&#xff09;是阿里巴巴开源的一款云原生服务发现和配置管理平台&#xff0c;支持多种语言。它提供了服务发现、配置管理、服务治理和流量管理等功能&#xff0c;使得微服务系统的构建和管理更加便捷。Nacos…

云HIS是什么?HIS系统为什么要上云?云HIS有哪些优点?

一、当前医疗行业HIS的现状与发展趋势 1.医院信息系统&#xff08;HIS&#xff09;经历了从手工到单机再到局域网的两个阶段&#xff0c;随着云计算、大数据新技术迅猛发展&#xff0c;基于云计算的医院信息系统将逐步取代传统局域网HIS , 以适应人们对医疗卫生服务越来越高的要…

关于EMC Unity 存储系统DIMM内存的几个问题

下面是客户咨询最多的几个关于EMC Unity的DIMM内存的问题&#xff0c;供大家参考。 1. Unity存储能否自己扩容内存 有客户觉得Unity存储的内容太小&#xff0c;想自己扩容内存&#xff0c;很朴实的想法&#xff0c;原来是每个控制器3条16gb&#xff0c;能不能升级到3条32gb或…

nvm安装

进入nvm github地址 https://github.com/nvm-sh/nvm 找到安装语句 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash 在终端中粘贴并运行 此时容易失败&#xff0c;可以配置一下hosts文件 将这个网址的配置地址加入到hosts文件中 https://g…

el-table控制列的显示与隐藏

1、序言 源码在下方&#xff0c;复制粘贴就可运行 当一个表格太多列的时候&#xff0c;想要显示/隐藏一些列&#xff0c;目标效果如下&#xff1a; 默认情况下&#xff0c;展示所有列 隐藏某一列 2、原理 &#xff08;1&#xff09;data数据有&#xff1a;tableData为表格数据&…

Apikit 自学日记:发起文档测试-Websocket

Websocket 进入某个WS协议的API文档详情页&#xff0c;点击文档上方 测试 标签&#xff0c;即可进入 API 测试页&#xff0c;系统会根据API文档的定义的求头部、Query参数、请求体自动生成测试界面并且填充测试数据。 填写/修改请求参数 1.1设置请求头部&#xff08;Header&…

6应用层-6.2【实验】【计算机网络】

6应用层-6.2【实验】【计算机网络】 前言推荐6应用层知识一、DNS常用记录类型&#xff1a;二、nslookup命令的用法 6.1 Web服务与FTP服务配置6.2 DNS域名系统配置实验目的实验内容及实验环境实验原理实验过程1.搭建如图所示的网络拓扑2.测试网络连通性3.在服务器上启用DNS服务&…

【Java核心技术】面向对象编程

面向对象编程 1、面向过程与面向对象面向过程(POP)与面向对象(OOP)面向对象的三大特征面向对象的思想概述 2、Java语言基本元素&#xff1a;类和对象类和对象类和对象的使用&#xff08;面向对象思想落地的实现&#xff09;对象的创建和使用&#xff1a;内存解析 3、类的成员之…

Anchor-free应用一览:目标检测、实例分割、多目标跟踪

作者&#xff5c;杨阳知乎 来源&#xff5c;https://zhuanlan.zhihu.com/p/163266388 本文整理了与Anchor free相关的一些工作。一方面是分享近期在目标检测领域中一些工作&#xff0c;另一方面&#xff0c;和大家一起梳理一下非常火热的网络模型CenterNet、FCOS&#xff0c;当…

IDEA下Logback.xml自动提示功能配置

首先打开logback的配置文件&#xff0c;在configuration标签中加入xsd的配置 <configuration xmlns"http://ch.qos.logback/xml/ns/logback"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://ch.qos.logback/xml…

消防通道堵塞识别 opencv

消防通道堵塞识别系统通过opencvpython网络模型技术&#xff0c;消防通道堵塞识别对消防通道的状态进行实时监测&#xff0c;检测到消防通道被堵塞时&#xff0c;将自动发出警报提示相关人员及时采取措施。OpenCV的全称是Open Source Computer Vision Library&#xff0c;是一个…