之前我一直在谈论依赖注入和代理。 现在首先看一下在Spring框架中所谓的重要便捷实用程序。 这些实用程序之一就是Spring的资源支持。
考虑一下如何尝试通过HTTP或FTP访问Java文件。 您可以使用Java的URL类并编写一些管道代码。
同样,如何从应用程序的类路径中读取文件? 或从Servlet上下文中,这意味着从Web应用程序的根目录(诚然,在现代的packaged.jar应用程序中,这种情况越来越少)。
同样,需要编写大量的样板代码才能正常工作,但不幸的是,每个使用案例(URL,类路径,Servlet上下文)的代码都会不同。
但是有一个解决方案:Spring的资源抽象。 用代码很容易解释。
import org.springframework.core.io.Resource;
public class MyApplication {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(someConfigClass); // (1)
Resource aClasspathTemplate = ctx.getResource("classpath:somePackage/application.properties"); // (2)
Resource aFileTemplate = ctx.getResource("file:///someDirectory/application.properties"); // (3)
Resource anHttpTemplate = ctx.getResource("https://marcobehler.com/application.properties"); // (4)
Resource depends = ctx.getResource("myhost.com/resource/path/myTemplate.txt"); // (5)
Resource s3Resources = ctx.getResource("s3://myBucket/myFile.txt"); // (6)
}
}
- 与往常一样,您需要一个ApplicationContext才能开始。
- 当在applicationContext上使用以classpath:开头的字符串调用getResource()时,Spring将在..well..application类路径上查找资源。
- 当使用以file:开头的字符串调用getResource()时,Spring将在硬盘上查找文件。
- 当使用以https :(或http)开头的字符串调用getResource()时,Spring将在Web上查找文件。
- 如果未指定前缀,则实际上取决于您配置的applicationContext类型。
- 对于Spring Framework,这不是开箱即用的,但是对于Spring Cloud等其他库,您甚至可以直接访问s3://路径。
简而言之,Spring能够通过漂亮的小语法访问资源。 资源接口有两种有趣的方法:
public interface Resource extends InputStreamSource {
boolean exists();
String getFilename();
File getFile() throws IOException;
InputStream getInputStream() throws IOException;
// ... other methods commented out
}
如你所见,它使你可以对资源执行最常见的操作:
- 是否存在?
- 文件名?
- 得到文件引用
- 直接得到数据(InputStream)
这样就可以使用资源来执行所需的所有操作,而不必依赖网络上,类路径或硬盘上的资源。
资源抽象看起来像是一个很小的功能,但是当与Spring提供的下一个便捷功能:Properties相结合时,它确实会发光。
什么是Spring Env?
任何应用程序的很大一部分都在读取属性,例如数据库用户名和密码,电子邮件服务器配置,Stripe付款明细配置等。
这些属性以最简单的形式存在于.properties文件中,并且可能有很多:
- 其中一些在类路径中,因此可以访问一些与开发相关的密码。
- 其他文件可能在文件系统或网络驱动器中,因此生产服务器可以具有自己的安全属性。
- 有些甚至可能以操作系统环境变量的形式出现。
Spring尝试通过其环境抽象使你轻松注册并自动在所有这些不同源中查找属性。
import org.springframework.core.env.Environment;
public class MyApplication {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(someConfigClass);
Environment env = ctx.getEnvironment(); // (1)
String databaseUrl = env.getProperty("database.url"); // (2)
boolean containsPassword = env.containsProperty("database.password");
// etc
}
}
- 通过applicationContext,始终可以访问当前程序的环境。
- 另一方面,Spring Env使你可以访问属性。
现在,到底什么是Spring ENV?
什么是Spring @PropertySoruces?
简而言之,环境由一对多的属性源组成。 例如:
- /mydir/application.properties
- classpath:/application-default.properties
(注意:环境也由配置文件组成,即“开发”或“生产”配置文件,当然这里不涉及这个)。
默认情况下,Spring MVC Web应用程序环境由ServletConfig / Context参数,JNDI和JVM系统属性源组成。 它们也是分层的,这意味着它们具有重要性顺序,并且彼此覆盖。
但是,自己定义新的@PropertySources很容易:
import org.springframework.context.annotation.PropertySources;
import org.springframework.context.annotation.PropertySource;
@Configuration
@PropertySources(
{@PropertySource("classpath:/com/${my.placeholder:default/path}/app.properties"),
@PropertySource("file://myFolder/app-production.properties")})
public class MyApplicationContextConfiguration {
// your beans
}
现在更有意义了,为什么我们以前谈论过Spring的资源。 因为两个功能齐头并进。
@PropertySource注解可与任何有效的Spring配置类一起使用,并允许您借助Spring的资源抽象来定义新的其他源:记住,这全都与前缀有关:http://,file://,classpath:等 。
通过@PropertySources定义属性很好,但是没有比必须通过环境访问属性更好的方法了吗? 有!
Spring @Value 和 Property 注入
你可以将属性注入到bean中,就像使用@Autowired批注注入依赖项一样。 但是对于属性,需要使用@Value批注。
import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Value;
@Component
public class PaymentService {
@Value("${paypal.password}") // (1)
private String paypalPassword;
public PaymentService(@Value("${paypal.url}") String paypalUrl) { // (2)
this.paypalUrl = paypalUrl;
}
}
- @Value 直接作用在字段上
- 或者构造器参数
到这里就差不多了, 每当使用@Value批注时,Spring都会遍历你的(分层)环境并寻找适当的属性-如果不存在这样的属性,则抛出错误消息。
个人博客: https://patrickchen.cn/
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/10038.html