欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring入门(六):条件化的bean

程序员文章站 2022-04-09 21:25:39
1. 概念 默认情况下,Spring中定义的bean在应用程序启动时会全部装配,不管当前运行的是哪个环境(Dev,QA或者Prod),也不管当前运行的是什么系统(Windows或者Linux),但有些使用场景下,我们可能需要条件化的装配某些bean,即当满足某一条件时,装配某些bean,当不满足某一 ......

1. 概念

默认情况下,spring中定义的bean在应用程序启动时会全部装配,不管当前运行的是哪个环境(dev,qa或者prod),也不管当前运行的是什么系统(windows或者linux),但有些使用场景下,我们可能需要条件化的装配某些bean,即当满足某一条件时,装配某些bean,当不满足某一条件时,就忽略掉某些bean。

这个条件可以很简单,比如当某个jar包存在时,当存在某个环境变量时,也可以很复杂。

针对这个使用场景,spring中提供了@conditional注解来实现条件化的bean。

2. 示例

为了更好的理解,我们通过具体的代码示例来理解下条件化的bean的实现方式。

由于windows系统和linux系统显示列表的命令不同,windows下是dir,linux下是ls,因此我们的需求是,应用程序启动时自动根据当前系统装配需要的bean,比如我的电脑系统是windows 7,那就只装配windows系统所需要的bean。

首先,定义一个接口listservice,该接口只包含一个方法showlistcmd:

package chapter03.conditional;

public interface listservice {
    string showlistcmd();
}

然后定义该接口的2个实现类windowslistservice和linuxlistservice:

package chapter03.conditional;

public class windowslistservice implements listservice {
    public windowslistservice() {
        system.out.println("this is windowslistservice constructor");
    }
    
    @override
    public string showlistcmd() {
        return "dir";
    }
}
package chapter03.conditional;

public class linuxlistservice implements listservice {
    public linuxlistservice() {
        system.out.println("this is linuxlistservice constructor");
    }
    
    @override
    public string showlistcmd() {
        return "ls";
    }
}

然后分别定义windows系统和linux系统的判断条件:

package chapter03.conditional;

import org.springframework.context.annotation.condition;
import org.springframework.context.annotation.conditioncontext;
import org.springframework.core.type.annotatedtypemetadata;

public class windowscondition implements condition {
    @override
    public boolean matches(conditioncontext conditioncontext, annotatedtypemetadata annotatedtypemetadata) {
        return conditioncontext.getenvironment().getproperty("os.name").contains("windows");
    }
}
package chapter03.conditional;

import org.springframework.context.annotation.condition;
import org.springframework.context.annotation.conditioncontext;
import org.springframework.core.type.annotatedtypemetadata;

public class linuxcondition implements condition {
    @override
    public boolean matches(conditioncontext conditioncontext, annotatedtypemetadata annotatedtypemetadata) {
        return conditioncontext.getenvironment().getproperty("os.name").contains("linux");
    }
}

值得注意的是,这2个类都需要实现condition接口,并重写方法matches(),如果该方法返回true时,使用该条件的1个或多个bean就会被装配,如果该方法返回false,使用该条件的1个或多个bean就会被忽略。

然后,定义java配置类conditionalconfig:

package chapter03.conditional;

import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.conditional;
import org.springframework.context.annotation.configuration;

@configuration
public class conditionalconfig {
    @bean
    @conditional(windowscondition.class)
    public listservice windowslistservice() {
        return new windowslistservice();
    }

    @bean
    @conditional(linuxcondition.class)
    public listservice linuxlistservice() {
        return new linuxlistservice();
    }
}

这里声明bean时除了使用@bean注解,还使用了@conditional注解,这个注解是实现条件化的bean的关键,它的参数可以传递任何实现了condition接口并重写了matches()方法的类,这里传递的是我们上面定义的windowscondition和linuxcondition。

最后,我们定义一个main类,在其main()方法中添加如下测试代码:

package chapter03.conditional;

import org.springframework.context.annotation.annotationconfigapplicationcontext;

public class main {
    public static void main(string[] args) {
        annotationconfigapplicationcontext context = new annotationconfigapplicationcontext(conditionalconfig.class);

        listservice listservice = context.getbean(listservice.class);

        system.out.println(context.getenvironment().getproperty("os.name") + "系统下的列表命令为:" + listservice.showlistcmd());

        context.close();
    }
}

运行结果如下所示:

this is windowslistservice constructor

windows 7系统下的列表命令为:dir

从运行日志可以看出,由于当前系统是windows 7,我们声明的linuxlistservice bean并没有被装配。

3. 源码及参考

源码地址:,欢迎下载。

汪云飞《java ee开发的颠覆者:spring boot实战》

craig walls 《spring实战(第4版)》

4. 最后

打个小广告,欢迎扫码关注微信公众号:「申城异乡人」,定期分享java技术干货,让我们一起进步。

Spring入门(六):条件化的bean