2.SpringBoot-Condition

文章介绍了如何使用SpringBoot的条件注解@Conditional来实现特定条件下创建Bean。通过一个实例展示了如何创建自定义条件注解ClassCondition和它的实现,以及如何在UserConfig中使用这些注解来决定是否实例化User对象。最后,通过SpringbootConditionApplication启动应用并获取Bean。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、 参考

04-SpringBoot自动配置-切换内置web服务器_哔哩哔哩_bilibili

二、 Condition

顾名思义:条件。有点类似于if语句,只不过是通过注解的形式来实现。

         以一个实际需求来学习该原理:有一个实体类User,想要创建该实例化对象,必须导入某第三方包(这个第三方包名必须可以自己设定),否则无法创建User的实例化对象。

 先看Project的结构,

        - ClassCondition.java :@ConditionOnClass注解的实现类,他人不可调用。

        - ConditionOnClass.java :注解,供他人调用的注解。

        - UserConfig.java :起控制作用,根据程序员设定的Conditioal判断是否新建User对象并返回。

        - User.java :实体类,bean类。

        - SpringbootConditionApplication.java:在此文件中获取User这个bean对象

举个例子:

        相当于一个水龙头流水的案例,User这个bean就是我们想接的水,UserConfig就是出水的那个管子,ClassCondition和@ConditionOnClass注解就是控制水流的水龙头,只不过ClassCondition是@ConditionOnClass注解的实际实现,外面的人使用@ConditionOnClass注解即可,不用关心水龙头里面的构造。

 

2.1 ClassCondition.java

        实现Condition接口,需要重写一个boolean matches()方法,该方法返回true/false,返回的真值就类似于if判断的结果。

package com.itheima.springbootcondition.condtion;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;

import java.util.Map;

public class ClassCondition implements Condition {
    /**
     *
     * @param context 上下文对象。用于获取环境,IOC容器,ClassLoader对象
     * @param metadata 注解元对象。 可以用于获取注解定义的属性值
     * @return
     */
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        /*
        //1.需求: 导入Jedis坐标后创建Bean
        //思路:判断redis.clients.jedis.Jedis.class文件是否存在
        boolean flag = true;
        try {
            Class<?> cls = Class.forName("redis.clients.jedis.Jedis");
        } catch (ClassNotFoundException e) {
            flag = false;
        }
        return flag;
        */

        //2.需求: 导入通过注解属性值value指定坐标后创建Bean

        //获取注解属性值  value
        Map<String, Object> map = metadata.getAnnotationAttributes(ConditionOnClass.class.getName());
        //System.out.println(map);
        String[] value = (String[]) map.get("value");

        boolean flag = true;
        try {
            for (String className : value) {
                Class<?> cls = Class.forName(className);
            }
        } catch (ClassNotFoundException e) {
            flag = false;
        }
        return flag;

    }
}

 2.2 ConditionOnClass.java

        这是一个注解类,右键Annotation即可新建。

        里面通过@Conditional(ClassCondition.class)来和他的实现类ClassCondition.java完成绑定,外面的人直接使用@ConditionOnClass注解即可,不用关系它的实现类ClassCondition是怎么实现的,相当于一层封装。

        里面有一个String数组value,这个就是用来将外面的人传递给注解的参数传递给实现类ClassCondition.java。

package com.itheima.springbootcondition.condtion;


import org.springframework.context.annotation.Conditional;

import java.lang.annotation.*;


@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)  //运行时指定
@Documented

//下面这个注解需要特别关注,就是考这个注解将ConditionOnClass和ClassCondition绑定到一起的
@Conditional(ClassCondition.class)
public @interface ConditionOnClass {
    String[] value();
}

 2.3 UserConfig.java

        @configuration注解对象,会自动加载其中的config,下面的config主要完成的功能就是根据程序员设定的conditional条件判断是否新建对象并返回给调用者。

        在这里面使用刚才新建的注解。

package com.itheima.springbootcondition.config;

import com.itheima.springbootcondition.condtion.ClassCondition;
import com.itheima.springbootcondition.condtion.ConditionOnClass;
import com.itheima.springbootcondition.domain.User;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

@Configuration
public class UserConfig {

    @Bean
    @ConditionOnClass("com.alibaba.fastjson.JSON")
    public User user(){
        return new User();
    }


    /**
     * 下面这个Case是调用现成的,不用我们自己写
     * @return
     */
    @Bean
    @ConditionalOnProperty(name = "itcast",havingValue = "itheima")
    public User user2(){
        return new User();
    }

}

2.4 User.java

实体对象类,自由添加即可。

package com.itheima.springbootcondition.domain;

public class User {
}

2.5 SpringbootConditionApplication.java

在此函数中调用UserConfig中的函数获取User这个bean的实例化对象。

package com.itheima.springbootcondition;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class SpringbootConditionApplication {

    public static void main(String[] args) {
        //启动SpringBoot的应用,返回Spring的IOC容器
        ConfigurableApplicationContext context = SpringApplication.run(SpringbootConditionApplication.class, args);
/*
        //获取Bean,redisTemplate
        Object redisTemplate = context.getBean("redisTemplate");
        System.out.println(redisTemplate);
        */


        Object user = context.getBean("user2");
        System.out.println(user);

    }

}

三、小结

大部分情况下不需要我们自己写。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ad_m1n

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值