Springboot核心注解
运行文中的代码需要在项目构建中引入springboot 相关依赖.
① @configuration
configuration,用来将bean加入到ioc容器。代替传统xml中的bean配置。代码示例:
定义一个普通类:
public class Person {
}
定义一个配置类,用来将此类注册到ioc容器中:
@Configuration
public class PersonConfig { @Bean
public Person person(){
return new Person();
} }
测试类:
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac=new AnnotationConfigApplicationContext(PersonConfig.class);
System.out.println(ac.getBean("person"));
}
}
运行结果:

② @ComponentScan
用来扫包,相当于xml配置的 :<context:component-scan base-package="" />
代码示例:
首先我们看一下项目的目录结构:

目前所有的类都是在CompentScanTest下面
一个普通的service bean:
@Service
public class UserService { }
一个配置类,这里会使用 @ComponentScan 注解:
@ComponentScan
public class ScanConfig { }
一个测试类:
public class CompentScanTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac=new AnnotationConfigApplicationContext(ScanConfig.class);
Stream.of(ac.getBeanDefinitionNames()).forEach(System.out::println);
}
}
运行结果:

本包下的加了注解的类都被扫描了,也就是说 @ComponentScan 默认扫描本包下面加了对应注解的类。
可以添加一个熟悉 然后测试 :
@ComponentScan(basePackages = "com.llicat.stage3.springboot")
public class ScanConfig { }
此时把configuration包下的类也会扫描出来:

还有其他的像排除之类的,这里不在复述。
③ @EnableAutoConfiguration
主要有两个注解:

@import 的说明:
xml 中有如下配置:
<import resource="classpath:spring-dao.xml"/> 引入其他配置文件的配置。
代码结构:

一个简单对象类:
public class SimpleBean {
}
配置类,用来把对象加入ioc容器:
@Configuration
public class SimpleBeanConfig { @Bean
public SimpleBean simpleBean(){
return new SimpleBean();
}
}
测试类:
public class App {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac=new AnnotationConfigApplicationContext(SimpleBeanConfig.class);
Stream.of(ac.getBeanDefinitionNames()).forEach(System.out::println);
System.out.println(ac.getBean("simpleBean"));
}
}
运行结果:

扫描了当前包下面存在注解的类。
在other包下面存在一个bean 和对应的配置类,我们修改一下代码:
@Configuration
@Import(OtherBeanConfig.class)
public class SimpleBeanConfig { @Bean
public SimpleBean simpleBean(){
return new SimpleBean();
}
}
然后运行发现,其他类也被扫描了。区别与compentScan @import 引入动态的配置类,可以使得扫描更加灵活和动态化


注意到这一个配置:

AutoConfigurationImportSelector实现了ImportSelector,importSelector是spring提供的一个用来支持动态注入的配置。这里可以模仿实现:
定义一个接口与两个实现类:
public interface Logger {
void doLogger();
}
public class DevLogger implements Logger {
@Override
public void doLogger() {
System.out.println("[DEBUG]...");
}
}
public class TestLogger implements Logger {
@Override
public void doLogger() {
System.out.println("[INFO]");
}
}
然后定义一个importSelector:
public class LoggerSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
Map<String, Object> include = importingClassMetadata.getAnnotationAttributes(EnableAutoSwitchLogger.class.getName());
Class [] clzs=null==include.get("include")?null:((Class[]) include.get("include"));
ArrayList<String> classList=new ArrayList<>();
Stream.of(clzs).forEach(clz->{
if(clz.isInterface()){
return;
}
classList.add(clz.getName());
});
return classList.toArray(new String[classList.size()]);
}
}
这个类主要是为了获取元数据信息,然后返回需要被扫描注入到ioc的类。
定义@EnableAutoSwitchLogger 并且使用LoggerSelector:
1 @Target(ElementType.TYPE)
2 @Retention(RetentionPolicy.RUNTIME)
3 @Documented
4 @Inherited
5 @Import(LoggerSelector.class)
6 public @interface EnableAutoSwitchLogger {
7
8 /**
9 * 这里可以指定要返回的日志实现类
10 * @return
11 */
12 Class<?>[] include() default {};
13 }
测试类:
1 @Configuration
2 @EnableAutoSwitchLogger(include ={TestLogger.class,DevLogger.class})
3 public class App {
4
5
6 public static void main(String[] args) {
7
8 AnnotationConfigApplicationContext ac=new AnnotationConfigApplicationContext(App.class);
9 Stream.of(ac.getBeanDefinitionNames()).forEach(System.out::println);
10 }
11
12 }
测试结果:

这个实际上就是springboot实现动态注入的一个关键点。分析AutoConfigurationImportSelector 的核心实现:
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(
autoConfigurationMetadata, annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
点进去loadMetadata,会加载配置文件,其实就是条件注解,只有当前扫描的路径下存在条件中配置的类 然后去加载spring.factories中对应的第三方类。为了保证性能,不能是所有依赖的第三方的jar的类都被
加载,而是你配置了,才会去加载。
protected static final String PATH = "META-INF/"
+ "spring-autoconfigure-metadata.properties"; private AutoConfigurationMetadataLoader() {
} public static AutoConfigurationMetadata loadMetadata(ClassLoader classLoader) {
return loadMetadata(classLoader, PATH);
}
getAutoConfigurationEntry方法调用了getCandidateConfigurations 使用了 spring中的spi工具类SpringFactoriesLoader去加载配置文件META-INF/spring.factories中key为
org.springframework.boot.autoconfigure.EnableAutoConfiguration(注解的全限定名),对应的value会作为字符串被返回,然后作为需要被加载到ioc中的信息。spi是用来spring用来把第三方的jar包里面的类加载到
ioc容器的一种技术,需要满足指定路径下指定文件,且key匹配。@configuration 扫包扫不到第三方jar包。
总结:
@SpringBootApplication=@ComponentScan+@Configuration+@EnableAutoConfiguration
ComponentScan用来指定当前包路径,在这个路径下的都会被扫描到,@Configuration 用来说明这是一个配置类,可以去加载bean到ioc中。@EnableAutoConfiguration ,核心依AutoConfigurationImportSelector的实现:首先在META-INF/spring.factories 中预先配置了许多默认需要被加载的bean,然后在 spring-autoconfigure-metadata.properties配置了,这些默认bean被加载的条件,
并且通过条件可以过滤不需要被加载的bean,为了满足更大的客户化需求,在使用 @SpringBootApplication 可以指定 exclude属性,这些会作为元素数据,去移除掉不需要加载的类,同时也可以使用@ConditionalOnClass 去指定需要满足某些条件,默认配置中的类才会被加载。
Springboot核心注解的更多相关文章
- 浅谈SpringBoot核心注解原理
SpringBoot核心注解原理 今天跟大家来探讨下SpringBoot的核心注解@SpringBootApplication以及run方法,理解下springBoot为什么不需要XML,达到零配置 ...
- SpringBoot核心注解应用
1.今日大纲 了解Spring的发展 掌握Spring的java配置方式 学习Spring Boot 使用Spring Boot来改造购物车系统 2.Spring的发展 Spring1.x 时代 在S ...
- SpringBoot的核心注解和配置
一.入口类和SpringBootApplication Spring Boot的项目一般都会有*Application的入口类,入口类中会有main方法,这是一个标准的Java应用程序的入口方法. @ ...
- 【SpringBoot】15. Spring Boot核心注解
Spring Boot核心注解 1 @SpringBootApplication 代表是Spring Boot启动的类 2 @SpringBootConfiguration 通过bean对象来获取配置 ...
- SpringBoot 核心配置
1. 入口类和 @SpringBootApplication Spring Boot的项目一般都会有*Application的入口类,入口类中会有main方法,这是一个标准的Java应用程序的入口方法 ...
- springboot深入学习(一)-----springboot核心、配置文件加载、日志配置
一.@SpringBootApplication @SpringBootApplication是spring boot的核心注解,源码如下: 相当于:@Configuration+@EnableAut ...
- 最新学习springboot 配置注解
一.概述 Spring Boot设计目的是用来简化新Spring应用的初始搭建以及开发过程.Spring Boot并不是对Spring功能上的增强,而是提供了一种快速使用Spring的方式. ...
- SpringBoot核心
1.基本配置 1.1入口类和@SrpingBootApplication SpringBoot通常有一个名为*Application的入口类,入口类里有一个main方法,这个main方法就是一个标准的 ...
- 读懂这些spring boot的核心注解,快速配置完成项目搭建
在spring boot中,摒弃了spring以往项目中大量繁琐的配置,遵循约定大于配置的原则,通过自身默认配置,极大的降低了项目搭建的复杂度.同样在spring boot中,大量注解的使用,使得代码 ...
随机推荐
- Fira Code字体安装与配置
俗话说,工欲善其事,必先利其器.算法固然重要,但真正实践也很重要. 一个字体的好看程度,直接决定了写代码和看代码的心情.比如这样: 代码1: #include <iostream> #in ...
- linux查找大文件及详细问题
查询大文件du -h --max-depth=1 查询指定目录下面的文件大小du -h --max-depth=1 /path 使用find命令查找大于200M文件 find / -type f -s ...
- 使用 Iceberg on Kubernetes 打造新一代云原生数据湖
背景 大数据发展至今,按照 Google 2003年发布的<The Google File System>第一篇论文算起,已走过17个年头.可惜的是 Google 当时并没有开源其技术,& ...
- C++语言学习之STL 的组成
STL有三大核心部分:容器(Container).算法(Algorithms).迭代器(Iterator),容器适配器(container adaptor),函数对象(functor),除此之外还有S ...
- Luogu P1856 [USACO5.5]矩形周长Picture
线段树+扫描线 经典的扫描线问题 首先将一个矩形看作由竖着的两条边和横着的两条边构成 那分成两次考虑,一次考虑竖边,一次考虑横边 首先考虑横边 如图两个矩形,现将横边擦去,留下竖边,将平面划分成3个区 ...
- 如何制作一本《现代Javascript教程》EPUB电子书
制作一本<现代Javascript教程>电子书学习使用 计划学习JavaScript的同学可以看过来,今天就推荐个学习JavaScript的免费教程. 教程文档来源于 https://zh ...
- 凯撒密码(Java)
事实上就是把每个字母偏移一下而已,并且字符不限于a-zA-z,可以是别的,那就很显而易见了,代码如下:定义一个Caesar密码类,成员变量只有密钥,也就是偏移量key 代码如下: public cla ...
- leetcode105: jump-game-ii
题目描述 给出一个非负整数数组,你最初在数组第一个元素的位置 数组中的元素代表你在这个位置可以跳跃的最大长度 你的目标是用最少的跳跃次数来到达数组的最后一个元素的位置 例如 给出数组 A =[2,3, ...
- Python_爬虫_Scrapy设置代理
0.检测IP是否可用 # -*- coding: UTF-8 -*- from urllib import request if __name__ == "__main__": # ...
- Win7 安装 Docker 踩的那些坑
公司电脑是 WIN7 x64 旗舰版 SP1,安装 Docker 时踩了好多雷,分享出来给大家排排雷. 首先,Docker Desktop Installer 的 Windows 版只支持 Win10 ...