[读书笔记] 二、条件注解@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读书笔记二
这是我的一些读书笔记: 我研究了一下面向对象: 面向对象符合人类看待事物的一般规律,对象的方法的实现细节是包装的,只有对象方法的实现者了解细节 我觉得面向过程是由过程.步骤.函数组成,过程是核心,面向 ...
随机推荐
- (转)log4j(七)——log4j.xml简单配置样例说明
背景:在公司中警察需要做技术支持,查看日志,而查看日志首先要自己清楚日志是如何生成的,所以有必要知道日志的前世今生! 转载出处:http://www.cnblogs.com/godtrue/p/644 ...
- 使用VMware安装CentOS
使用VMware安装CentOS 第1步:首先安装VMware Workstation,只需点下一步即可,安装过程略 第2步:文件 → 新建虚拟机 或 直接点击 创建新的虚拟机 图标 第3步:选择 典 ...
- 再起航,我的学习笔记之JavaScript设计模式03
我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 上一 ...
- jQuery全选、全不选、反选的简洁写法【实例】
全选方面的功能几乎是每个需要列表展示的网站所必不可少的,当然此功能也有很多种写法,现在介绍一下,比较简洁易懂的写法: <input type="checkbox" name= ...
- 小兴趣:修改Hosts文件,禁止访问指定网页
不知道Hosts文件什么鬼的朋友可以在网上搜索一下(大牛勿喷- -) 访问网址时,先查询本地的Hosts文件,那么如果我们将Hosts文件中的网址与IP的映射修改之后,将访问错误的IP. 如在文件尾追 ...
- MyEclipse Web 项目导入 Eclipse 中需要改的文件
来自为知笔记(Wiz)
- 7种方法解决移动端Retina屏幕1px边框问题
在Reina(视网膜)屏幕的手机上,使用CSS设置的1px的边框实际会比视觉稿粗很多.在之前的项目中,UI告诉我说我们移动项目中的边框全部都变粗了,UI把他的设计稿跟我的屏幕截图跟我看,居然真的不一样 ...
- ArrayList 和 LinkedList的执行效率比较
一.概念: 一般我们都知道ArrayList* 由一个数组后推得到的 List.作为一个常规用途的对象容器使用,用于替换原先的 Vector.允许我们快速访问元素,但在从列表中部插入和删除元素时,速度 ...
- mysql的内连接,外连接(左外连接,右外连接)巩固
1:mysql的内连接: 内连接(inner join):显示左表以及右表符合连接条件的记录: select a.goods_id,a.goods_name,b.cate_name from tdb_ ...
- 敏捷视界:Scrum起源、Scrum术语
Scrum起源 Scrum的原始含义 Scrum原始含义是指英式橄榄球次要犯规时在犯规地点对阵争球.争球双方各有8个队员参与,各方出3名前锋队员,并肩各站成一横排,面对面躬身互相顶肩,中间形成一条通道 ...