首页 > 其他分享 >Spring IOC官方文档学习笔记(十三)之环境概要

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

时间:2023-02-28 22:46:22浏览次数:39  
标签:Profile profile 概要 ExampleA Spring ctx new IOC public

1.profiles

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

//假定现在我们存在开发和生产两个环境,每种环境下ExampleA所需的url都是不同的,那么我们就可以使用@Profile注解,来声明在哪种环境下该注入哪种bean
@Configuration
public 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属性值不仅可以为一个字符串值,亦可以为一个表达式,规则如下:

  • ! : 逻辑非

  • | : 逻辑或

  • & : 逻辑与

@Configuration
public 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方法来设置激活哪一个profile
ctx.getEnvironment().setActiveProfiles("production");
ctx.register(Config.class);
ctx.refresh();
Arrays.stream(ctx.getBeanDefinitionNames()).forEach(System.out::println);

//例二:指定多个配置信息,观察打印结果,可见两个ExampleA都被注入到容器中
//setActiveProfiles方法可同时激活多个profile
ctx.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属性值不相同
@Configuration
public 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类中两个方法的位置,如下
@Configuration
public 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的配置中,我们可以指定<beans/>标签中profile属性的值,来进行配置,如下

<!-- 相当于在@Configuration类上添加了@Profile("prod")注解 -->
<beans profile="prod" ....>
    <!-- bean的定义... -->

</beans>

<!-- 在xml的配置中,profile的属性值不能使用像注解那样的表达式,比如前面的表达式:production & (online | offline) 是不能用于xml中的,不过xml支持 ! 运算符 -->
<beans profile="!prod" ....>
    <!-- bean的定义... -->

</beans>

<!-- 虽然xml中不支持表达式,但为了表达出 &(与) 的效果,我们可以这样声明 -->
<beans ...>
    
    <!-- 等价于@Profile("prod & online") -->
    <beans profile="prod">
        <beans profile="online">
            <!-- bean的定义... -->
        </beans>
    </beans>
</beans>

(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概要

未完待续...

标签:Profile,profile,概要,ExampleA,Spring,ctx,new,IOC,public
From: https://www.cnblogs.com/shame11/p/17159116.html

相关文章

  • spring整合web
    在service层开启的时候创建spring容器,在listener初始化的时候获取,然后将spring容器存储到servletContext中创建listener,重写里面的初始化方法contextInitializedpackage......
  • 【SpringCloud】feign.codec.EncodeException: No qualifying bean of type
    错误描述在SpringCloud项目中通过OpenFeign远程调用时出现如下错误:feign.codec.EncodeException:Noqualifyingbeanoftype'org.springframework.boot.autocon......
  • SpringBoot整合Spring Security
    1快速入门在项目中直接引入SpringSecurity的依赖<!--springSecurity--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-bo......
  • 初始spring MVC
    一.spring MVC的特点:轻量级,简单易学高效,基于请求响应的MVC架构与spring的兼容性好,无缝结合约定优于配置功能强大:RESTful,数据验证,格式化,本地化,主题等;Spring的web......
  • 理论:第二章:Spring的AOP和IOC是什么?使用场景有哪些?Spring事务与数据库事务,传播行为,数据
    AOP:面向切面编程。即在一个功能模块中新增其他功能,比方说你要下楼取个快递,你同事对你说帮我也取一下呗,你就顺道取了。在工作中如果系统中有些包和类中没有使用AOP,例如日志......
  • Preparing for Spring Boot 3.0 | Spring Boot 3.0 升级 实战踩坑记录
    PreparingforSpringBoot3.0https://spring.io/blog/2022/05/24/preparing-for-spring-boot-3-0SpringBoot3.0.0的到来,我们将会面临着那些问题-掘金https://jue......
  • Spring事务管理的方式
    ①编程式事务管理:通过编写代码实现的事务管理,包括定义事务的开始、正常执行后的事务提交和异常时的事务回滚。②声明式事务管理:通过AOP技术实现的事务管理,其主要思想是将......
  • Spring/Spring Boot下如何动态配置计划任务
    和Spring对异步任务的支持一样,通过@EnableAsync 注解开启异步的支持,然后通过@Async 注解来指定异步的方法,而真正的异步任务的执行者是TaskExecutor接口 ,它的实现是Threa......
  • SpringBoot 访问html
    1、pom.xml文件配置<dependency><!--页面模板依赖--><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</a......
  • 数据库简介及概要
    1、数据库简介:数据库(Database,DB)是一个长期存储在计算机内的、有组织的、有共享的、统一管理的数据集合。简单来讲就是可以放大量数据的地方。管理数据库的计算机系统......