title: Sring Boot 自动装配 date: 2019-07-18 categories:
SpringBoot和新特性笔记。
@sevice
@Conrtroller
@Repository
@Component
这几个注解在 Srping源码
的文章中已经将结果了,这里就不在赘述了。
Condition
注解作为条件,如果符合条件则将 bean
注入到 IOC
中,反之则不注入,实际是使用 @Conditional
注解来实现,继承 Condition
接口,通过 matches
方法进行逻辑判断是否符合条件。
/** * @Auther: lantao * @Date: 2019-07-18 17:52 * @Company: 随行付支付有限公司 * @maill: lan_tao@suixingpay.com * @Description: TODO */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) @Documented @Conditional({SysPropertyCondition.class}) public @interface ConditionOnSysProperty { String value() default "lantao"; } 复制代码
/** * @Auther: lantao * @Date: 2019-07-18 17:52 * @Company: 随行付支付有限公司 * @maill: lan_tao@suixingpay.com * @Description: TODO */ public class SysPropertyCondition implements Condition { /** * 匹配方法 * * @param context * @param metadata * @return */ @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { // 获取 ConditionOnSysProperty 注解的属性 Map<String, Object> attributes = metadata.getAnnotationAttributes(ConditionOnSysProperty.class.getName()); String value = String.valueOf(attributes.get("value")); // 获取本机的user.name值 String propertieValue = System.getProperties().get("user.name").toString(); // 对比 return value.equals(propertieValue); } } 复制代码
/** * @Auther: lantao * @Date: 2019-07-18 17:44 * @Company: 随行付支付有限公司 * @maill: lan_tao@suixingpay.com * @Description: TODO */ public class ConditionBootStrap { @Bean // 这了因为value是lantao, 正好user.name也是lantao,所以条件成立,会将bean注入到ioc中 @ConditionOnSysProperty(value = "lantao") private String helloWorld() { return "Hello World ! Condition"; } public static void main(String[] args) { // 这种方式可以不使用 SpringBootApplication 注解 ConfigurableApplicationContext context = new SpringApplicationBuilder(ConditionBootStrap.class).run(args); // 获取名为 helloWorld 的Bean,判断 ConditionOnSysProperty 条件是否生效 String helloWorld = context.getBean("helloWorld", String.class); System.out.println(helloWorld); // 关闭 context.close(); } } 结果: Hello World ! Condition 复制代码
Eanble
注解内部使用 @Import
将 bean
注入到 ioc
中, @import
注解中可以直接放入 bean
,也可以做更灵活的配置,使用继承了 ImportSeletor
接口的bean,可以根据 @Enable
注解的 属性(attrbutes)
进行灵活的动态判断 /** * @Auther: lantao * @Date: 2019-07-18 18:03 * @Company: 随行付支付有限公司 * @maill: lan_tao@suixingpay.com * @Description: TODO */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented // 直接使用无法灵活判断 //@Import(TestConfiguration.class) // 使用 HelloWorldImportSeletor 可以有更灵活的判断 @Import(HelloWorldImportSeletor.class) public @interface EnableHelloWorld { String name() default "lantao"; } 复制代码
public class TestConfiguration { @Bean private String helloWorld() { return "hello World! Enable"; } } public class Test1Configuration { @Bean public String buzhidao() { return "不知道"; } } 复制代码
/** * @Auther: lantao * @Date: 2019-07-19 09:55 * @Company: 随行付支付有限公司 * @maill: lan_tao@suixingpay.com * @Description: TODO */ public class HelloWorldImportSeletor implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { // 获取EnableHelloWorld注解的属性 Map<String, Object> attributes = importingClassMetadata.getAnnotationAttributes(EnableHelloWorld.class.getName()); // 根据attributes 灵活判断注入那个bean if ("lantao".equals(attributes.get("name"))) { System.out.println(TestConfiguration.class.getName()); return new String[]{TestConfiguration.class.getName()}; } System.out.println(TestConfiguration.class.getName()); return new String[]{Test1Configuration.class.getName()}; } } 复制代码
/** * @Auther: lantao * @Date: 2019-07-18 18:04 * @Company: 随行付支付有限公司 * @maill: lan_tao@suixingpay.com * @Description: TODO */ @EnableHelloWorld //@EnableHelloWorld(name = "buzhidao") public class EnableBootStrap { public static void main(String[] args) { // 这种方式可以不使用 SpringBootApplication 注解 ConfigurableApplicationContext context = new SpringApplicationBuilder(EnableBootStrap.class).run(args); // 获取名为 helloWorld 的Bean,判断 ConditionOnSysProperty 条件是否生效 String helloWorld = context.getBean("helloWorld", String.class); // 这里可以获取 bean名称为 'buzhidao',需要注解@EnableHelloWorld(name = "buzhidao"), // 因为@EnableHelloWorld的name默认值是lantao,符合Condition的条件判断 // String helloWorld = context.getBean("buzhidao", String.class); System.out.println(helloWorld); // 关闭 context.close(); } } 结果: hello World! Enable 复制代码
/** * @Auther: lantao * @Date: 2019-07-22 10:10 * @Company: 随行付支付有限公司 * @maill: lan_tao@suixingpay.com * @Description: TODO */ @EnableHelloWorld @ConditionOnSysProperty(value = "lantao") @Configuration public class SpringFactoriesConfiguration { // 这里没有写 bean 的注入,直接引用 Condition 和 eanble 模块注解。 // eanble注解内部使用import将bean注入到ioc中,@import注解中可以直接放入bean,也可以做更灵活的配置使用继承了ImportSeletor接口的bean, // 可以根据enable注解的属性(attrbutes)进行灵活的动态判断 // Condition 注解作为条件,如果符合条件则将bean注入到IOC中,反之则不注入,实际是使用 @Conditional注解来实现,通过继承 Condition 接口, // 通过 matches 方法进行逻辑判断是否符合条件。 } 复制代码
# Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=/ com.lantao.springboot_leran.spring_factories_leran.config.SpringFactoriesConfiguration 复制代码
/** * @Auther: lantao * @Date: 2019-07-19 16:01 * @Company: 随行付支付有限公司 * @maill: lan_tao@suixingpay.com * @Description: TODO */ @EnableAutoConfiguration public class SpringFactoriesBootStrap { public static void main(String[] args) { ConfigurableApplicationContext context = new SpringApplicationBuilder(SpringFactoriesBootStrap.class).run(args); String helloWorld = context.getBean("helloWorld", String.class); System.out.println(helloWorld); context.close(); } } 结果: hello World! Enable 复制代码