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中,大量注解的使用,使得代码 ...
随机推荐
- 「APIO2015」巴邻旁之桥 Palembang Bridges
贪心 先转化一下题意 首先如果一个人的家和办公室在河同一侧那么建桥的时候不用去考虑它,最终把答案加上即可 在河两侧的家和办公室互换不影响答案,那么可以把这个抽象到一个区间$[l,r]$,距离就是$|l ...
- ArrayList使用及原理
之前面试时,经常被问到ArrayList的原理,今天整理了一些ArrayList的使用原理和必问的知识点. ArrayList的继承关系 定义一个ArrayList的方法 ArrayList的三个构造 ...
- ros启动节点Error: package 'chapter2_tutorials' not found问题
在学习ROS时,实现节点之间的通信时,参考ROS机器人高效编程,每次启动节点的时候 $ rosrun chapter2_tutorials example1_a 都会提示 Error: package ...
- 【SpringBoot】06.SpringBoot访问静态资源
SpringBoot访问静态资源 1.SpringBoot从classpath/static的目录 目录名称必须是static 启动项目,访问http://localhost:8080/0101.jp ...
- C语言I博课作业04
这个作业属于哪个课程 C语言程序设计II 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/SE2020-1/homework/11489 我在这个作业课程 ...
- java中保留两位小数的方法
1.BigDecimal的setScale // RoundingMode 舍入模式: // 1.UP/DOWN ->基准为数字0: // 2.CEILING/FLOOR ->基准为正负无 ...
- 经典c程序100例==61--70
[程序61] 题目:打印出杨辉三角形(要求打印出10行如下图) 1.程序分析: 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 2.程序源代码: main() ...
- ubuntu mplayer "无法打开 VDPAU backend libvdpau ..."
gnome mplayer 报错"无法打开 VDPAU backend libvdpau_nvidia.so: cannot open shared object file: No such ...
- java8-lambda-list中字符出现字数的统计
@Test public void testStringCount(){ List<String> moidList1 = new ArrayList<>(); moidLis ...
- Linux标准输入、标准输出、错误输出
Linux中的输入文件.输出文件.错误输出 文件名称 文件描述符 标准输入 0 (默认是键盘) 标准输出 1 (默认是屏幕) 标准错误 2 (默认是屏幕) 输出重定向 Linux中&表示后台运 ...