1. Bean的Scope
1.1 基础知识
Scope描述的是Spring容器如何新建Bean的实例的。Spring的Scope有以下几种,通过@Scope注解实现。
- Singleton:一个Spring容器只有一个Bean的实例,此为Spring的默认配置,全容器共享一个实例。
- Prototype:每次调用新建一个Bean的实例。
- Request:Web项目中,给每一个http request新建一个Bean实例。
- Session:Web项目中,给每一个http session新建一个Bean实例。
- GlobalSession:这个只在portal应用中有用,给每一个global http session 新建一个Bean实例。
1.2 示例
(1)编写Singleton的Bean。
import org.springframework.stereotype.Service;
@Service //1
public class DemoSingletonService {
}
代码解释
- 注释1:默认为Singleton,相当于@Scope("singleton").
(2)编写Prototype的Bean
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
@Service
@Scope("prototype") //1
public class DemoPrototypeService {
}
代码解释
- 注释1:声明Scope为Prototype。
(3)配置类。
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("scope")
public class ScopeConfig {
}
(4)运行。
运行结果显示,通过DemoSingletonService创建的两个Bean实例相等;通过DemoPrototypeService创建的两个Bean实例不等。
2. Spring EL和资源调用
2.1 基础知识
Spring EL-Spring表达式语言,支持在xml和注解中使用表达式,类似于JSP的EL表达式语言。
Spring开发中经常涉及调用各种资源的情况,包含普通文件、网址、配置文件、系统环境变量等,都可以使用Spring的表达式语言实现资源的注入。
具体分为以下几种情况:
(1)注入普通字符。
@Value("I Love You!")
private String normal;
(2)注入操作系统属性。
@Value("#{systemProperties['os.name']}")
private String osName;
(3)注入表达式运算结果。
@Value("#{ T(java.lang.Math).random() * 100.0 }")
private double randomNumber;
(4)注入其他Bean的属性。
@Value("#{demoService.another}")
private String fromAnother;
(5)注入文件内容。
@Value("classpath:../test.txt")
private Resource testFile;
(6)注入网址内容。
@Value("http://www.baidu.com")
private Resource testUrl;
(7)注入属性文件。
@Value("${book.name}")
private String bookName;
3. Bean的初始化和销毁
3.1 基础知识
由于一些在 Bean 使用之前或者之后的必要操作,Spring 对 Bean 的生命周期操作提供了支持。在 Java 配置和注解配置下提供如下两种方式:
(1)Java 配置方式:使用 @Bean 的 initMethod 和 destoryMethod(相当于 xml 配置的 init-method 和 destory-method)。
(2)注解方式:利用JSR-250的 @PostConstruct(在构造函数执行完之后执行) 和 @PreDestroy(在Bean销毁之前执行)。
4. Profile
4.1 基础知识
Profile 为在不同环境下使用不同的配置提供了支持。
(1) 通过设定 Environment 的 ActiveProfiles 来设定当前 context 需要使用的配置环境。在开发中使用 @Profile 注解类或者方法,达到在不同情况下选择实例化不同的 Bean。
(2)通过设定 jvm 的 spring.profiles.active 参数来设置配置环境。
(3)Web项目设置在 Servlet 的 context parameter 中。
- Servlet 3.0 及以上:
public class WebInit implements WebAppicationInitializer {
@Override
public void onStartup(ServletContext container) throws ServletException {
container。setInitParameter("spring.profiles.default", "dev");
}
}
4.2 示例
(1)示例Bean。
public class DemoBean {
private String content;
public DemoBean(String content) {
super();
this.content = content;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
(2)Profile 配置。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Configuration
public class ProfileConfig {
@Bean
@Profile("dev") //1
public DemoBean devDemoBean() {
return new DemoBean("from development profile");
}
@Bean
@Profile("pord") //2
public DemoBean prodDemoBean() {
return new DemoBean("from production profile");
}
}
代码解释
- 注释1:Profile 为 dev 时实例化 devDemoBean。
- 注释2:Profile 为 prod 时实例化 prodDemoBean。
5. 事件(Application Event)
5.1 基础知识
Spring 的事件(Application Event) 为 Bean 与 Bean 之间的消息通信提供了支持。当一个 Bean 处理完一个任务之后,希望另外一个 Bean 知道并能做出相应的处理,这是我们就需要让另外一个 Bean 监听当前 Bean 所发送的事件。
Spring 的事件需要遵循如下流程:
(1)自定义事件,继承 ApplicationEvent。
(2)定义事件监听器,实现 ApplicationListener。
(3)使用容器发布事件。
5.2 示例
(1)自定义事件。
import org.springframework.context.ApplicationEvent;
public class DemoEvent extends ApplicationEvent {
public static final long serialVersionUID = 1L;
private String msg;
public DemoEvent(Object source, String msg) {
super(source);
this.msg = msg;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
(2)事件监听器
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
@Component
public class DemoListener implements ApplicationListener<DemoEvent> {//1
@Override
public void onApplicationEvent(DemoEvent demoEvent) { //2
String msg = demoEvent.getMsg();
System.out.println("我(bean-demoListener)接收到了bean-demoPublisher发布的消息:" + msg);
}
}
代码解释
- 注释1:实现 ApplicationListener 接口,并指定监听的事件类型。
- 注释2:使用onApplicationEvent 方法对消息进行接受处理。
(3)事件发布类
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class DemoPublisher {
@Autowired
ApplicationContext applicationContext; //1
public void publish(String msg) {
applicationContext.publishEvent(new DemoEvent(this,msg)); //2
}
}
代码解释
- 注释1:注入 ApplicationContext 用来发布事件。
- 注释2:使用 ApplicationContext 的 publishEvent 方法来发布。