SpringBoot手动装配,自定义Enable模块
前言
前面我们介绍了简单详细的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
- 点赞
- 收藏
- 关注作者
评论(0)