[读书笔记] 二、条件注解@Conditional,组合注解,元注解
一、条件注解@Conditional,组合注解,元注解
1.
@Conditional:满足特定条件创建一个Bean,SpringBoot就是利用这个特性进行自动配置的。
例子:
首先,两个Condition,判断当前系统是否是Windows或者Linux(True False)
然后,2个ListService实现类,表明不同系统下的ListService实现。
主要,ConditionConfig使用了Java配置与@Conditional注解,根据LinuxCondition,或者WindowsCondition作为判断条件
产生相应与系统匹配的实现类。
最后,App.java 测试成功。
package com.springboot.springboot_test2_1; import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata; public class LinuxCondition implements Condition { @Override
public boolean matches(ConditionContext arg0, AnnotatedTypeMetadata arg1) {
return arg0.getEnvironment().getProperty("os.name").contains("Linux");
} }
LinuxCondition.java
package com.springboot.springboot_test2_1; import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata; public class WindowsCondition implements Condition { @Override
public boolean matches(ConditionContext arg0, AnnotatedTypeMetadata arg1) {
return arg0.getEnvironment().getProperty("os.name").contains("Windows");
} }
WindowsCondition.java
package com.springboot.springboot_test2_1; public interface ListService {
public String showListCmd();
}
ListService.java
package com.springboot.springboot_test2_1; public class LinuxListService implements ListService{ @Override
public String showListCmd() {
return "ls";
} }
LinuxListService.java
package com.springboot.springboot_test2_1; public class WindowsListService implements ListService{ @Override
public String showListCmd() {
return "dir";
} }
WindowsListService.java
package com.springboot.springboot_test2_1; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration; @Configuration
public class ConditionConfig { @Bean
@Conditional(WindowsCondition.class)
public ListService windowsListService() {
return new WindowsListService();
} @Bean
@Conditional(LinuxCondition.class)
public ListService linuxListService() {
return new LinuxListService();
} }
ConditionConfig.java
package com.springboot.springboot_test2_1; import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; /**
* Hello world!
*
*/
public class App {
public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(
ConditionConfig.class); ListService ls = context.getBean(ListService.class);
System.out.println(context.getEnvironment().getProperty("os.name")
+ "系统下的列表命令为:" + ls.showListCmd());
}
}
App.java
2.
元注解:可以注解到别的注解上的注解。
组合注解:元注解+被注解=组合注解。
例子:
package com.springboot.springboot_test2_1; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; @Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
@ComponentScan
public @interface testConfig {
String[] value() default{};
}
testConfig.java
二、通过条件注解@Conditional,组合注解,元注解理解SpringBoot的自动配置
@SpringBootApplication,源码:
@Target({java.lang.annotation.ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters={@org.springframework.context.annotation.ComponentScan.Filter(type=org.springframework.context.annotation.FilterType.CUSTOM, classes={org.springframework.boot.context.TypeExcludeFilter.class}), @org.springframework.context.annotation.ComponentScan.Filter(type=org.springframework.context.annotation.FilterType.CUSTOM, classes={AutoConfigurationExcludeFilter.class})})
public @interface SpringBootApplication
{
@AliasFor(annotation=EnableAutoConfiguration.class, attribute="exclude")
Class<?>[] exclude() default {}; @AliasFor(annotation=EnableAutoConfiguration.class, attribute="excludeName")
String[] excludeName() default {}; @AliasFor(annotation=ComponentScan.class, attribute="basePackages")
String[] scanBasePackages() default {}; @AliasFor(annotation=ComponentScan.class, attribute="basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};
}
SpringBootApplication源码
它的核心功能是由@EnableAutoConfiguration注解提供的,
@EnableAutoConfiguration,源码:
@SuppressWarnings("deprecation")
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; /**
* Exclude specific auto-configuration classes such that they will never be applied.
* @return the classes to exclude
*/
Class<?>[] exclude() default {}; /**
* Exclude specific auto-configuration class names such that they will never be
* applied.
* @return the class names to exclude
* @since 1.3.0
*/
String[] excludeName() default {}; }
EnableAutoConfiguration源码
@EnableAutoConfiguration其中的@AutoConfigurationPackage,会扫描/META-INF/spring.factories文件中的jar包,
spring.factories文件如下:
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
……
2、核心注解
spring.factories文件里每一个xxxAutoConfiguration文件一般都会有下面的条件注解:
@ConditionalOnBean:当容器里有指定Bean的条件下
@ConditionalOnClass:当类路径下有指定类的条件下
@ConditionalOnExpression:基于SpEL表达式作为判断条件
@ConditionalOnJava:基于JV版本作为判断条件
@ConditionalOnJndi:在JNDI存在的条件下差在指定的位置
@ConditionalOnMissingBean:当容器里没有指定Bean的情况下
@ConditionalOnMissingClass:当类路径下没有指定类的条件下
@ConditionalOnNotWebApplication:当前项目不是Web项目的条件下
@ConditionalOnProperty:指定的属性是否有指定的值
@ConditionalOnResource:类路径是否有指定的值
@ConditionalOnSingleCandidate:当指定Bean在容器中只有一个,或者虽然有多个但是指定首选Bean
@ConditionalOnWebApplication:当前项目是Web项目的条件下。
上面@ConditionalOnXXX都是组合@Conditional元注解,使用了不同的条件Condition
[读书笔记] 二、条件注解@Conditional,组合注解,元注解的更多相关文章
- Java开发笔记(八十二)注解的基本单元——元注解
Java的注解非但是一种标记,还是一种特殊的类型,并且拥有专门的类型定义.前面介绍的五种内置注解,都可以找到对应的类型定义代码,例如查看注解@Override的源码,发现它的代码定义是下面这样的: @ ...
- spring揭秘 读书笔记 二 BeanFactory的对象注册与依赖绑定
本文是王福强所著<<spring揭秘>>一书的读书笔记 我们前面就说过,Spring的IoC容器时一个IoC Service Provider,而且IoC Service Pr ...
- spring揭秘 读书笔记 二 BeanFactory的对象注冊与依赖绑定
本文是王福强所著<<spring揭秘>>一书的读书笔记 我们前面就说过,Spring的IoC容器时一个IoC Service Provider,并且IoC Service Pr ...
- ES6读书笔记(二)
前言 前段时间整理了ES6的读书笔记:<ES6读书笔记(一)>,现在为第二篇,本篇内容包括: 一.数组扩展 二.对象扩展 三.函数扩展 四.Set和Map数据结构 五.Reflect 本文 ...
- 《你必须知道的.NET》读书笔记二:小OO有大原则
此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.单一职责原则 (1)核心思想:一个类最好只做一件事,只有一个引起它变化的原因 (2)常用模式:Fa ...
- Mastering Web Application Development with AngularJS 读书笔记(二)
第一章笔记 (二) 一.scopes的层级和事件系统(the eventing system) 在层级中管理的scopes可以被用做事件总线.AngularJS 允许我们去传播已经命名的事件用一种有效 ...
- 【记】《.net之美》之读书笔记(二) C#中的泛型
前言 上一篇读书笔记,很多小伙伴说这本书很不错,所以趁着国庆假期,继续我的读书之旅,来跟随书中作者一起温习并掌握第二章的内容吧. 一.理解泛型 1.为什么要使用泛型?-----通过使用泛型,可以极大地 ...
- how tomcat works 读书笔记(二)----------一个简单的servlet容器
app1 (建议读者在看本章之前,先看how tomcat works 读书笔记(一)----------一个简单的web服务器 http://blog.csdn.net/dlf123321/arti ...
- java读书笔记二
这是我的一些读书笔记: 我研究了一下面向对象: 面向对象符合人类看待事物的一般规律,对象的方法的实现细节是包装的,只有对象方法的实现者了解细节 我觉得面向过程是由过程.步骤.函数组成,过程是核心,面向 ...
随机推荐
- 如何制作一个完美的全屏视频H5
写在前面的话: 最近一波H5广告火爆整个互联网圈,身为圈内人,我们怎能 不! 知!道! :( 嘘!真不知道的也继续看下去,有收获 ↓ ) So,搞懂这个并不难. 这篇文章将带你从头到尾了解H5 ...
- java多态加深
当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法. public class Dtai ...
- Quartz.Net 与 Autofac 自动注入 的整合问题
一.问题发现 今天早上在用 Quartz.Net 做定时扫描异常队列的功能模块时,发现处理异常队列的Job里面的ILog对象服务,Autofac没有自动注入进来. 然后在网上查阅相关资料,无奈发现 Q ...
- javascript中typeof和instanceof用法的总结
今天在看相应的javascript书籍时,遇到了typeof和instanceof的问题,一直不太懂,特地查资料总结如下: JavaScript 中 typeof 和 instanceof 常用来判断 ...
- phpunit实践笔记
phpunit成为单元测试的代名词已成为共识, 但很多在实际编写测试过程中遇到的很多问题通过手册.网上搜索都很难找到相关资料, 大部分都得通过查看源代码和实践的代码经验解决.欢迎大家拍砖.(在此之前请 ...
- 一次花费了一两个小时的mysql问题排查
晚上把博客迁了个服务器,新建用户的时候遇到问题了. 关于mysql的问题. 前置操作 建了两个用户,一个laravel,一个blog用户以及他们的同名数据库. 建好之后,命令行下面连接mysql服务, ...
- Flunetd 用于统一日志记录层的开源数据收集器
传统的日志查看方式 使用fluentd之后 一.介绍 Fluentd是一个开源的数据收集器,可以统一对数据收集和消费,以便更好地使用和理解数据. 几大特色: 使用JSON统一记录 简单灵活可插拔架构 ...
- NLPIR大数据挖掘平台新增敏感词扫描功能
在网络日益发达的现在,也伴随着有益信息与造成不稳定因素的信息也随之日益泛滥,为了网民的思想健康,也为了社会的和谐,在许多对外公共场合下,有些内容是要经过审查才能显示的.在网络审查初期,都是通过人工审核 ...
- C#控制台应用程序之旅游资源与线路管理系统
利用C#语言及SQL Server数据库编写的一个简化版旅游资源与线路管理系统 数据库中包含三张表:hotel表.tourist_spot表.lines表 用户分为管理员和普通用户,管理员拥有最高权限 ...
- 【万能的搜索,用广搜来解决DP问题】ZZNU -2046 : 生化危机 / HDU 1260:Tickets
2046 : 生化危机 时间限制:1 Sec内存限制:128 MiB提交:19答案正确:8 题目描述 当致命的T病毒从Umbrella Corporation 逃出的时候,地球上大部分的人都死去了. ...