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概要
(1) PropertySource是对配置参数的抽象,Spring会将我们的JVM系统变量和系统环境变量抽象成PropertySource实例,然后,当我们想要获得某个配置参数的值时,Spring便会在这些PropertySource实例上进行搜索,如下
首先通过IDEA配置一个JVM系统变量my-property,其值为boke
接着启动容器,如下,观察打印结果,会发现可以获取到我们所配置的JVM系统变量my-property的值
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
Environment env = ctx.getEnvironment();
System.out.println(env.getProperty("my-property"));
(2) 我们还可以获取到操作系统中的变量,如下,在用户变量中配置我们我们的属性值
接着,重启IDEA,再启动容器,观察打印结果,会发现已经获取到了我们的系统变量的值,当然,这个前提是(1)中我们所向configurations中Environment variables配置的变量已被删除,否则,存在两个相同的配置时,以Environment variables中的配置值优先(即JVM系统变量的优先级高于系统环境变量)
3.使用@PropertySource注解
(1) 在一般情况下,我们会将我们的配置项写进一个专门的配置文件中,而不会像上面中的例子那样去设置JVM系统变量或系统环境变量,当设置好了后,便可使用@PropertySource注解来读取我们所定义的配置文件了,如下所示
首先在resources目录下新建一个application.properties文件,其包含一个配置项如下
user=aaa
public class ExampleA {
public ExampleA(String s) {
System.out.println(s);
}
}
//在我们的Configuration类上使用@PropertySource注解,指定配置文件的路径(此处采用类路径),那么Spring便会加载解析这个配置文件,之后,从Environment中获取到我们所定义的配置值
@Configuration
@PropertySource("classpath:/application.properties")
public class Config {
@Autowired
private Environment environment;
@Bean
public ExampleA exampleA() {
return new ExampleA(environment.getProperty("user"));
}
}
//当然,更一般的,我们会采用@Value注解来读取配置文件中的配置项,它使用了${ }语法,其中大括号中的值为我们所需的键值
@Configuration
@PropertySource("classpath:/application.properties")
public class Config {
@Value("${user}")
private String username;
@Bean
public ExampleA exampleA() {
return new ExampleA(username);
}
}
(2) ${ }语法还可用于更一般的场景,如下所示
首先在resources目录下新建一个文件夹为boke,将我们的application.properties配置文件迁移到此文件夹下
---resources
|---boke
|---application.properties
接着再通过IDEA配置一个JVM系统变量mypath,其值为boke
然后我们就可以使用${ }来充当占位符,如下@PropertySource注解中的属性值存在一个占位符${mypath},在容器启动后,Spring会从环境变量中解析这个占位符,将其替换为真正的值,此处为boke
@Configuration
@PropertySource("classpath:/${mypath}/application.properties")
public class Config {
@Value("${user}")
private String username;
@Bean
public ExampleA exampleA() {
return new ExampleA(username);
}
}
我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain
matlab打开matlab,用最简单的imread方法读取一个图像clcclearimg_h=imread('hua.jpg');返回一个数组(矩阵),往往是a*b*cunit8类型解释一下这个三维数组的意思,行数、数和层数,unit8:指数据类型,无符号八位整形,可理解为0~2^8的数三个层数分别代表RGB三个通道图像rgb最常用的是24-位实现方法,即RGB每个通道有256色阶(2^8)。基于这样的24-位RGB模型的色彩空间可以表现256×256×256≈1670万色当imshow传入了一个二维数组,它将以灰度方式绘制;可以把图像拆分为rgb三层,可以以灰度的方式观察它figure(1
之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总
深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal
我试图在rails中了解rubygems是如何变得可以自动使用的,而不是在使用required的文件中gem? 最佳答案 这是通过bundler/setup完成的:http://bundler.io/v1.3/bundler_setup.html.它在您的config/boot.rb文件中是必需的。简而言之,它首先将环境变量设置为指向您的Gemfile:ENV['BUNDLE_GEMFILE']||=File.expand_path('../../Gemfile',__FILE__)然后它通过要求bundler/setup将所有ge
我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or
Ruby有一些不错的文档生成器,例如Yard、rDoc,甚至Glyph。问题是Sphinx可以做网站、PDF、epub、LaTex等。它在重组文本中完成所有这些事情。在Ruby世界中有替代方案吗?也许是程序的组合?如果我也能使用Markdown就更好了。 最佳答案 自1.0版以来,Sphinx有了“域”的概念,它是从Python和/或C以外的语言标记代码实体(如方法调用、对象、函数等)的方法。有一个rubydomain,所以你可以只使用Sphinx本身。您唯一会缺少的(我认为)是Sphinx使用autodoc从源代码自动创建文档
从一开始,我就是一个Windows高手。我从MS-DOS开始。我安装了Windows2.1以及此后的所有Windows。现在,我家里有10台不同的Windows机器在运行,从Windows7Ultimate到各种版本的WindowsServer。我还没有完成Windows8,也不想去那里。我在服务器和各种软件方面都有UNIX经验,但它并不是我的首选环境。但是,我想我正在转换。我试图假装使用Cygwin和MSYS在Windows下运行UNIX。我的目的是搭建一个开发环境。两者都让我失望了。我花了比开发更多的时间来解决一系列技术问题。这是NotAcceptable。到目前为止,我的Ruby