SpringBoot手动装配,自定义Enable模块

举报
码农飞哥 发表于 2021/05/29 13:25:28 2021/05/29
【摘要】 前言 前面我们介绍了简单详细的SpringBoot自动配置原理解析,今天这篇文章主要是介绍下如何是实现手动配置,自定义Enable模块, 基于注解驱动实现 基于注解的驱动实现是最基本的自定义Enable模块,它是不带条件的装配。首先我们来看看如何来实现! 第一步: 定义好配置类 这里定义了配置类SayHelloWorldConfiguration publi...

前言

前面我们介绍了简单详细的SpringBoot自动配置原理解析,今天这篇文章主要是介绍下如何是实现手动配置,自定义Enable模块,

基于注解驱动实现

基于注解的驱动实现是最基本的自定义Enable模块,它是不带条件的装配。首先我们来看看如何来实现!

第一步: 定义好配置类

这里定义了配置类SayHelloWorldConfiguration

public class SayHelloWorldConfiguration { @Bean SayHelloWorld sayHelloWorld() { System.out.println("********加载HelloConfig"); return new SayHelloWorld(); }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

这里就是实例化SayHelloWorld类,添加@Bean注解表明该方法实例化的对象会被加载到IOC容器之中。

第二步:定义EnableXXX注解

这里定义EnableHello注解,并且通过@Import注解将SayHelloWorldConfiguration配置类导入并加载到IOC容器。

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
//引入HelloConfig配置类
@Import({SayHelloWorldConfiguration.class})
public @interface EnableHello {

}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

第三步:在SpringBoot的启动类上添加Enable注解

至此基于注解驱动的手动配置就好了。启动之后我们就可以拿到实例化后的SayHelloWorld对象。但是,他这个是不能带任何条件的。

基于选择器实现的手动配置

与基于注解驱动的不同的是,基于选择器实现的手动配置需要增加一个选择器。步骤如下:

第一步 自定义选择器,实现ImportSelector

public class HelloWorldImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata annotationMetadata) { //获取注解上的属性 Map<String, Object> annotationAttributes = annotationMetadata.getAnnotationAttributes(EnableSelectorHelloWorld.class.getName()); Boolean isLinux = (Boolean) annotationAttributes.get("isLinux"); return new String[]{isLinux ? SayHelloWorldConfiguration.class.getName() : SayHelloWorldConfiguration2.class.getName()}; }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

这个选择器可以根据注解中传入的参数,返回不同的配置类,如上,当注解中的isLinux为true时,返回的配置类是SayHelloWorldConfiguration,否则,返回的配置类是SayHelloWorldConfiguration2

第二步:定义Enable注解

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({HelloWorldImportSelector.class})
public @interface EnableSelectorHelloWorld { boolean isLinux();
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这里引入的是我们前面定义的选择器类。
后面的步骤跟基于注解驱动实现一致,在此就不在赘述了。

条件装配

如果某些配置类需要满足一定的条件才能启动,该如何实现呢?这就需要用到条件装配了。条件装配的配置步骤如下:

第一步:定义Condition的实现类

public class OnSystemPropertyCondition implements Condition { @Override public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { //获取注解属性 Map<String, Object> attrs = annotatedTypeMetadata.getAnnotationAttributes(ConditionalOnSystemProperty.class.getName()); //获取系统值 String system = String.valueOf(attrs.get("value")); String currentOs = System.getProperty("os.name"); boolean result = currentOs.contains(system); System.out.println("********currentOs=" + currentOs + "匹配结果是=" + result); return result; }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

这里的代码也比较简单,就是根据ConditionalOnSystemProperty注解传入的value值,是否包含在当前系统的系统名中,如果是的话则返回true。否则,返回false。返回true的话,则会加载配置类中通过@Bean定义的对象。

第二步:定义配置类

public class SayHelloWorldConfiguration2 { /** * @return */ @ConditionalOnSystemProperty(value = "Windows") @Bean SayHelloWorld sayHelloWorld() { System.out.println("*********开始装配SayHelloWorld"); return new SayHelloWorld(); }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

定义Enable注解

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({SayHelloWorldConfiguration2.class})
public @interface EnableConditionHelloWorld {
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

总结

手动装配其实也是很简单的。上面就简单的示例了三种情况下的装配。希望对读者朋友们有所帮助。

源码下载

源码下载

文章来源: feige.blog.csdn.net,作者:码农飞哥,版权归原作者所有,如需转载,请联系作者。

原文链接:feige.blog.csdn.net/article/details/107964940

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。