本次主要讲点与Bean有关的常用配置。
Bean的Scope
Scope也就是作用域,描述Spring容器创建Bean实例的过程。有以下几种,使用@Scope注解来实现。
- Singleton: 一个Spring容器只有一个Bean实例,全Spring容器共享一个实例,此为默认配置。
- Prototype: 每次调用新创建一个实例。
- Request: Web项目中,每个request创建一个实例。
- Session: 同上,每个Session一个实例。
示例:
1 2 3 4 5 6
| @Scope("prototype") @Component() public class Song { }
|
Spring EL和资源调用
Spring开发中经常涉及到调用各种资源的情况,包含普通文件,网址,配置文件,系统环境变量等。我们可以使用Spring的 EL来实现资源的注入。
直接看示例
在resrouces文件夹下创建props/test.properties, 并添加
创建java config类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| package com.adu.config;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment;
@Configuration @PropertySource("classpath:props/test.properties") @ComponentScan("com.adu") public class ElConfig {
@Value("I Love you") private String normal;
@Value("#{systemProperties['os.name']}") private String osName;
@Value("#{T(java.lang.Math).random() * 100.0}") private Double randomNumber;
@Value("#{anotherService.name}") private String fromAnother;
@Value("${author.name}") private String authorName;
@Autowired private Environment environment;
public void outputResource() { System.out.println(normal); System.out.println(osName); System.out.println(randomNumber); System.out.println(fromAnother); System.out.println(authorName); System.out.println(environment.getProperty("author.name")); } }
package com.adu.service;
import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service;
@Service public class AnotherService {
@Value("another service") private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; } }
|
运行程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package com.adu.run;
import com.adu.config.ElConfig; import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Demo { public static void main(String[] args) { final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ElConfig.class); ElConfig elConfig = context.getBean(ElConfig.class); elConfig.outputResource(); context.close(); } }
|
Bean的初始化和销毁
在实际开发的时候,经常会遇到需要在Bean创建后和销毁后需要做些必要的操作。Spring对Bean的生命周期的操作提供了支持。有两种方式来使用。
- Java配置方式: 使用@Bean注解的initMethod 和destroyMethod(相当于xml配置中的init-method和destroy-method)
- 注解方式: 利用JSR-250的@PostConstruct和@PreDestroy
- @PostConstruct: 在构造函数执行完之后执行
- @PreDestroy: 在Bean销毁之前执行
一般使用注解方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Service public class AnotherService {
@Value("another service") private String name;
@PostConstruct private void initMethod() { }
@PreDestroy public void preDestroy() { } }
|
事件(Application Event)
Spring的事件为Bean与Bean之间的消息通信提供了支持。当一个bean处理完一个任务后,希望另一个bean知道并能做相应的处理,这时候我们就需要另一个Bean来监听这个bean发送的事件。以前不知道还有这种操作。
Spring的事件遵循一下流程:
- 自定义事件,继承ApplicationEvent.
- 定义事件监听器, 实现ApplicationListener.
- 使用容器发布事件。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| public class MessageEvent extends ApplicationEvent{
private String msg; public MessageEvent(Object source, String msg) { super(source); this.msg = msg; }
public String getMsg() { return msg; }
public void setMsg(String msg) { this.msg = msg; } }
@Component public class MessageListener implements ApplicationListener<MessageEvent> {
@Override public void onApplicationEvent(MessageEvent event) { String msg = event.getMsg(); System.out.println("I(Message Listener) accepted message from publisher: " + msg); } }
@Component public class MessagePublisher { @Autowired private ApplicationContext context;
public void publish(String msg) { context.publishEvent(new MessageEvent(this, msg)); } }
public class Demo { public static void main(String[] args) { final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ElConfig.class); MessagePublisher publisher = context.getBean(MessagePublisher.class); publisher.publish("hello, nice to meet you"); context.close(); } }
|
Application Event真的时超级简单,在实际应用中可以尝试一下。在某些需要协同服务时,应该是有很大应用空间的。