1 Bean 的 Scope
Scope 描述的是 Spring 容器如何创建 Bean 实例的.
Spring 的 @Scope
的 value 取值常见的有以下几种:
- singleton: 一个 Spring 容器中只有一个 Bean 的实例, 全容器共享一个实例.
@Scope
的默认值就是 Singleton. - prototype: 每次调用新建一个 Bean 实例.
- request: web 项目中, 给每一个 http request 新建一个 Bean 实例.
- session: web 项目中, 给每一个 http session 新建一个 Bean 实例.
- GlobalSession: 只在 portal 应用中有用, 给每个 global http session 新建一个 Bean 实例.
示例:
@Service
@Scope("prototype")
public class DemoPrototypeService {
}
2 Spring EL 和资源调用
在开发过程中, 有时会涉及到 调用别的资源的问题, 比如: 文件资源, 系统环境变量等.
Spring EL(Expression Language) 可以实现资源注入.
看个示例(源码地址).
配置一个 Bean:
@Service
public class DemoService {
@Value("其他类的属性")
public String another;
}
配置一个 properties 文件:
user.englishname=Rosie C
user.age=26
多种注入 属性值 的方式:
@Configuration
@ComponentScan("cn.mitrecx.learn3commonconfig.el")
@PropertySource("cn/mitrecx/learn3commonconfig/el/test.properties")
public class ElConfig {
// 注入普通字符串
@Value("Hi~ Rosie.")
private String normalStr;
// 注入操作系统属性
@Value("#{systemProperties['os.name']}")
private String osName;
// 注入数学表达式结果
@Value("#{T(java.lang.Math).random() * 100.0}")
private double randomNumber;
// 注入其他 Bean 的属性
@Value("#{demoService.another}")
private String fromAnother;
/**
* 注入配置文件, 需要 {@link ElConfig#propertyConfigure()} 配合使用
*/
@Value("${user.englishname}")
private String name;
/**
* 需要和 {@link PropertySource} 注解配合使用
*/
@Autowired
private Environment environment;
/**
* 此方法需要和 {@link PropertySource} 注解配合使用
*/
@Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigure() {
return new PropertySourcesPlaceholderConfigurer();
}
// 注入文件资源(流)
@Value("classpath:cn/mitrecx/learn3commonconfig/el/test.properties")
private Resource testFile;
// 注入 Url 资源(html页面流)
@Value("http://www.baidu.com")
private Resource testUrl;
public void outputResource() {
try {
System.out.println(normalStr);
System.out.println(osName);
System.out.println(randomNumber);
System.out.println(fromAnother);
System.out.println(name);
System.out.println(environment.getProperty("user.age"));
System.out.println(IOUtils.toString(testFile.getInputStream()));
System.out.println(IOUtils.toString(testUrl.getInputStream()));
} catch (Exception e) {
e.printStackTrace();
}
}
}
结果:
Hi~ Rosie.
Mac OS X
16.979522517362934
其他类的属性
Rosie C
26
user.englishname=Rosie C
user.age=26
...
3 Bean 的初始化和销毁
在 Bean 初始化之后 可以执行一个方法; 在 Bean 销毁之前 也可以执行一个方法.
有两种实现 Bean 初始化和销毁时执行操作的方式:
- Java 配置方式: 使用
@Bean
的initMethod
和destroyMethod
; - 注解方式: 利用 JSR-250 的
@PostConstruct
和@PreDestroy
.
代码演示.
4 Profile
Profile 为在不同环境下 使用不同的配置 提供了支持.
通过 Environment.ActiveProfiles
设置当前 context 的环境(dev 或 prod);
在类或方法上加 @Profile
注解指定 Bean 在实例化时具体的选择.
例如:
public class ProfileConfig {
@Bean
@Profile("dev")
public DemoBean devDemoBean() {
return new DemoBean("development profile...");
}
@Bean
@Profile("prod")
public DemoBean prodDemoBean() {
return new DemoBean("production profile...");
}
}
示例代码.
5 事件(ApplicationEvent)
Spring 的 ApplicationEvent
为 Bean 之间的消息通信提供了支持.
当一个 Bean 处理完一个任务后, 希望另外一个 Bean 知道并做相应的处理, 这种场景下就可以使用事件.
Spring 事件开发步骤:
- 自定义事件, 继承
ApplicationEvent
; - 自定义监听器, 实现
ApplicationListener
; - 使用容器发布事件.
示例代码.
Reference
[1]. Spring Boot 实战 - 汪云飞