最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

快资讯丨Spring IOC官方文档学习笔记(十三)之环境概要

来源:博客园

1.profiles


(相关资料图)

(1) profiles提供了一种在不同环境(Environment)下注册不同的bean的机制,如下

//假定现在我们存在开发和生产两个环境,每种环境下ExampleA所需的url都是不同的,那么我们就可以使用@Profile注解,来声明在哪种环境下该注入哪种bean@Configurationpublic class Config {    //development环境下注入该bean    @Bean    @Profile("development")    public ExampleA exampleAForDevelopment() {        return new ExampleA("http://127.0.0.1:8080");    }    //production环境下注入该bean    @Bean    @Profile("production")    public ExampleA exampleAForProduction() {        return new ExampleA("http://192.168.7.70:8080");    }}

@Profile属性值不仅可以为一个字符串值,亦可以为一个表达式,规则如下:

  • ! : 逻辑非

  • | : 逻辑或

  • & : 逻辑与

@Configurationpublic class Config {    //使用逻辑或,声明在development或test环境下注入这个bean ExampleA    @Bean    @Profile("development | test")    public ExampleA exampleAForDevelopment() {        return new ExampleA("http://127.0.0.1:8080");    }        //声明在production环境下且online或offline中至少某一种环境被激活下注入这个bean    @Bean    @Profile("production & (online | offline)")    public ExampleA exampleAForProduction() {        return new ExampleA("http://192.168.7.70:8080");    }}//例一:只声明profile为production,观察打印结果,可见未有任何ExampleA被注入到容器中AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();//使用Environment中的setActiveProfiles方法来设置激活哪一个profilectx.getEnvironment().setActiveProfiles("production");ctx.register(Config.class);ctx.refresh();Arrays.stream(ctx.getBeanDefinitionNames()).forEach(System.out::println);//例二:指定多个配置信息,观察打印结果,可见两个ExampleA都被注入到容器中//setActiveProfiles方法可同时激活多个profilectx.getEnvironment().setActiveProfiles("production", "online", "test");

(2) @Profile注解可用作元注解,用于创建自定义组合注解

//下面这个@Production注解,等价于@Profile("production")注解@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Profile("production")public @interface Production {}

(3) 对于重载的@Bean方法,@Profile会先校验其中的第一个方法,如果它不通过,则后面所有它的重载方法也全部不通过,否则,在上一个重载方法通过后,它才会继续接下来的剩余重载方法的校验,例子如下

//该Config类中有两个重载方法exampleA,它们的profile属性值不相同@Configurationpublic class Config {    @Bean    @Profile("dev")    public ExampleA exampleA(@Value("aaa") String str) {        return new ExampleA();    }    @Bean    @Profile("prod")    public ExampleA exampleA() {        return new ExampleA();    }}//先设置active-profile为prod,如下,启动容器,会发现容器抛出NoSuchBeanDefinitionException异常,这就是因为容器先校验了exampleA(String str)这个方法,发现它的profile为dev,不符,因此,后面的它的重载方法exampleA()也直接不通过,故而没有一个ExampleA实例被装入到容器中AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();ctx.getEnvironment().setActiveProfiles("prod");ctx.register(Config.class);ctx.refresh();System.out.println(ctx.getBean(ExampleA.class));//对于上面的例子,我们只颠倒Config类中两个方法的位置,如下@Configurationpublic class Config {    @Bean    @Profile("prod")    public ExampleA exampleA() {        return new ExampleA();    }    @Bean    @Profile("dev")    public ExampleA exampleA(@Value("aaa") String str) {        return new ExampleA();    }}//然后,再次启动容器,会发现我们获得了一个ExampleA实例,这就是因为容器先校验了exampleA(),其profile值与active-profile值一致,通过,接下来校验exampleA(String str),结果不通过,因此会有一个ExampleA实例被注入到容器中

(4) 在基于xml的配置中,我们可以指定标签中profile属性的值,来进行配置,如下

                                                    

(5) 在前面的例子中,我们已经看到了,可通过Environment中的setActiveProfiles()方法来选择激活某一个或多个profile,除此之外,我们还可以通过配置spring.profiles.active的属性值来声明激活哪些profile,这个spring.profiles.active可在springboot项目中的yml配置文件中进行配置,或通过jvm系统参数来进行配置,如下

(6) profile的默认属性值为default,可通过Environment中的setDefaultProfiles()方法或指定spring.profiles.default的属性值来进行修改

//@Profile("default")代表启用默认配置,即如果当前Environment中没有任何profile被指定,那么这个bean就会被添加到容器中,反之,如果指定了任何profile,那么这个bean就会被排除在外@Configuration@Profile("default")public class Config {    @Bean    public ExampleA exampleA() {        return new ExampleA();    }}

2.PropertySource概要

未完待续...

关键词: 再次启动 进行修改 字符串值