@Conditional---Spring源码从入门到精通(四)

简介: @Conditional---Spring源码从入门到精通(四)

上篇文章:

@Scope&@Lazy---Spring源码从入门到精通(三)


大家是否都用过System.getProperties.getPropertite(“os.name”),获取过登入系统,这篇文章就看Conditional注解源码,如何获取系统信息。


@Conditional作用只有一个实例会给ComponentScan扫描(好多文章说的是只有一个实例给容器管理,我的理解是不对的,ComponentScan扫描之后才给容器,如果被过滤了,容器里面就没有)。所以他在ComponentScan过滤之前进行。


从conditional源码里可以看到,制定了两个elementType,可以放在方法上,也可以放在类上。先放目录,这篇文章主要新增两个condition类

image.png


1、Conditional放在方法上


先写两个bean,一个mac,一个Linux,然后定义macConditional和linuxCondition代码如下。

/**
 *
 * @author keying
 */
@Configuration
//满足conditional条件,这个类的配置信息才可以生效
//@Conditional({LinuxCondition.class})
public class BeanConfig2 {
    @Scope
    @Lazy
    @Bean(value = "person")
    public Person getPerson(){
        System.out.println("把bean交给容器管理");
        return new Person("person2",19);
    }
    /**
     * @Conditional判断条件,满足就放入容器
     *
     */
    @Bean(value = "Mac")
    @Conditional({MacCondition.class})
    public Person getMac(){
        return new Person("Mac",1);
    }
    @Bean(value = "Linux")
    @Conditional({LinuxCondition.class})
    public Person getLinux(){
        return new Person("Linux",2);
    }
}

写两个condition,下面是判断mac的示例:

/**
 * 判断mac
 *
 * @author keying
 * @date 2021/6/27
 */
public class MacCondition implements Condition {
    /**
     *
     * @param context 判断条件使用的上下文
     * @param metadata 注释信息
     * @return
     */
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        //1、ioc使用的bean工厂
        ConfigurableListableBeanFactory configurableListableBeanFactory = context.getBeanFactory();
        //2、类的加载器
        ClassLoader classLoader = context.getClassLoader();
        //3、环境
        Environment environment = context.getEnvironment();
        //4、定义bean
        BeanDefinitionRegistry beanDefinitionRegistry = context.getRegistry();
        String name = environment.getProperty("os.name");
        if(name.contains("Mac")){
            return true;
        }
        return false;
    }
}

最后执行junit测试:

 @org.junit.Test
    public void test3(){
     /*   String[] beanNames = annotationConfigApplicationContext.getBeanDefinitionNames();
        for (String beanName : beanNames) {
            System.out.println(beanName);
        }*/
        String[] names = annotationConfigApplicationContext.getBeanNamesForType(Person.class);
        System.out.println("===========");
        for (String name : names) {
            System.out.println(name);
        }
        Map<String,Person> map = annotationConfigApplicationContext.getBeansOfType(Person.class);
        System.out.println(map);
      /*  ConfigurableEnvironment configurableEnvironment = annotationConfigApplicationContext.getEnvironment();
        String name = configurableEnvironment.getProperty("os.name");
        System.out.println(name);*/
    }

输出的结果可以看到,linux系统的并没有打印出来,而mac的就打印出来了。

image.png


2、Conditional放在类上


/**
 *
 * @author keying
 */
@Configuration
//满足conditional条件,这个类的配置信息才可以生效
@Conditional({LinuxCondition.class})
public class BeanConfig2 {
    @Scope
    @Lazy
    @Bean(value = "person")
    public Person getPerson(){
        System.out.println("把bean交给容器管理");
        return new Person("person2",19);
    }
    /**
     * @Conditional判断条件,满足就放入容器
     *
     */
    @Bean(value = "Mac")
    @Conditional({MacCondition.class})
    public Person getMac(){
        return new Person("Mac",1);
    }
    @Bean(value = "Linux")
    public Person getLinux(){
        return new Person("Linux",2);
    }
}


当放在类上在执行可以看到,结果打印的是空的,因为当前类只能在linux系统情况下,才加载:

image.png


相关文章
|
21天前
|
缓存 Java 开发工具
Spring是如何解决循环依赖的?从底层源码入手,详细解读Spring框架的三级缓存
三级缓存是Spring框架里,一个经典的技术点,它很好地解决了循环依赖的问题,也是很多面试中会被问到的问题,本文从源码入手,详细剖析Spring三级缓存的来龙去脉。
Spring是如何解决循环依赖的?从底层源码入手,详细解读Spring框架的三级缓存
|
21天前
|
缓存 安全 Java
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
从底层源码入手,通过代码示例,追踪AnnotationConfigApplicationContext加载配置类、启动Spring容器的整个流程,并对IOC、BeanDefinition、PostProcesser等相关概念进行解释
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
|
21天前
|
XML 缓存 Java
手写Spring源码(简化版)
Spring包下的类、手写@ComponentScan注解、@Component注解、@Autowired注解、@Scope注解、手写BeanDefinition、BeanNameAware、InitializingBean、BeanPostProcessor 、手写AnnotationConfigApplicationContext
手写Spring源码(简化版)
|
5天前
|
缓存 Java Spring
手写Spring Ioc 循环依赖底层源码剖析
在Spring框架中,IoC(控制反转)是一个核心特性,它通过依赖注入(DI)实现了对象间的解耦。然而,在实际开发中,循环依赖是一个常见的问题。
15 4
|
11天前
|
XML 缓存 Java
spring源码剖析-spring-beans(内部核心组件,BeanDefinition的注册,BeanWapper创建)
spring源码剖析-spring-beans(内部核心组件,BeanDefinition的注册,BeanWapper创建)
39 10
|
11天前
|
XML 存储 Java
spring源码刨析-spring-beans(内部核心组件,beanDefinition加载过程)
spring源码刨析-spring-beans(内部核心组件,beanDefinition加载过程)
|
10天前
|
XML 存储 Java
Spring-源码深入分析(二)
Spring-源码深入分析(二)
|
10天前
|
XML 设计模式 Java
Spring-源码深入分析(一)
Spring-源码深入分析(一)
|
2月前
|
人工智能 前端开发 Java
【实操】Spring Cloud Alibaba AI,阿里AI这不得玩一下(含前后端源码)
本文介绍了如何使用 **Spring Cloud Alibaba AI** 构建基于 Spring Boot 和 uni-app 的聊天机器人应用。主要内容包括:Spring Cloud Alibaba AI 的概念与功能,使用前的准备工作(如 JDK 17+、Spring Boot 3.0+ 及通义 API-KEY),详细实操步骤(涵盖前后端开发工具、组件选择、功能分析及关键代码示例)。最终展示了如何成功实现具备基本聊天功能的 AI 应用,帮助读者快速搭建智能聊天系统并探索更多高级功能。
594 2
【实操】Spring Cloud Alibaba AI,阿里AI这不得玩一下(含前后端源码)
|
2月前
|
缓存 Java Spring
Spring缓存实践指南:从入门到精通的全方位攻略!
【8月更文挑战第31天】在现代Web应用开发中,性能优化至关重要。Spring框架提供的缓存机制可以帮助开发者轻松实现数据缓存,提升应用响应速度并减少服务器负载。通过简单的配置和注解,如`@Cacheable`、`@CachePut`和`@CacheEvict`,可以将缓存功能无缝集成到Spring应用中。例如,在配置文件中启用缓存支持并通过`@Cacheable`注解标记方法即可实现缓存。此外,合理设计缓存策略也很重要,需考虑数据变动频率及缓存大小等因素。总之,Spring缓存机制为提升应用性能提供了一种简便快捷的方式。
37 0
下一篇
无影云桌面