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中,大量注解的使用,使得代码 ...
随机推荐
- 热部署只知道devtools吗?JRebel不香吗?
持续原创输出,点击上方蓝字关注我 目录 前言 JRebel收费怎么破? 什么是本地热部署? 什么是远程热部署? JRebel和devtools的区别 如何安装JRebel? 如何本地热部署? 如何远程 ...
- P2346 四子连棋
P2346 四子连棋 迭代加深++ 题意描述 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋 ...
- 动态规划入门——动态规划与数据结构的结合,在树上做DP
本文由TechFlow原创,本博文仅作为知识点学习,不会用于任何商业用途! 今天我们来看一个有趣的问题,通过这个有趣的问题,我们来了解一下在树形结构当中做动态规划的方法. 这个问题题意很简单,给定一棵 ...
- SAP S/4HANA 2020安装实录
欢迎关注微信公众号:sap_gui (ERP咨询顾问之家) 今天开始试着安装SAP S/4HANA 2020版本,也是目前SAP ERP最高的版本,总安装文件大小大概50GB,数据库版本必须是HANA ...
- CI框架导入 excel
整合PHP Excel和PHPexcelReader到 librarys下面 两个excel整合成一个excel <?php class Excel extends Control ...
- excel导出csv包括逗号等的处理
/** * @Title: trimRubbishChar * @Description: 导出的时候需要对一格的内容进行检查,看是否有非法字符,以免串行 * @Since: 2016年8月2日 下午 ...
- 1. 安装虚拟机,Hadoop和Hive
由于想自学下Hive,所以前段时间在个人电脑上安装了虚拟机,并安装上Hadoop和Hive.接下我就分享下我如何安装Hive的.步骤如下: 安装虚拟机 安装Hadoop 安装Java 安装Hive 我 ...
- 用GitHub Pages搭建博客(六)
本篇介绍GitHub Pages网站加速 在上一篇提到如何对GitHub Pages配置自定义域名.其实,不论GitHub Pages的默认域名还是自定义域名,都使用了GitHub的CDN进行加速,虽 ...
- delete和truncate/drop恢复数据的过程
使用myflash工具恢复delete操作数据,myflash工具注意事项: 该工具注意事项 1.binlog格式必须为row,且binlog_row_image=full 2.仅支持5.6与5.7 ...
- 我要进大厂之大数据MapReduce知识点(2)
01 我们一起学大数据 今天老刘分享的是MapReduce知识点的第二部分,在第一部分中基本把MapReduce的工作流程讲述清楚了,现在就是对MapReduce零零散散的知识点进行总结,这次的内容大 ...