一、Bean的Scope
1. 介绍
- Scope描述的是Spring容器是如何新建Bean的实例。
- Singleton:一个Spring容器只有一个实例。
- Prototype:每次调用都会新建一个Bean的实例。
2. 需求
Singleton和Prototype,分别从Spring容器中获得两次Bean,判断是否相等
3. 示例
①. 编写Singleton的Bean
package com.eleven.scope1;
import org.springframework.stereotype.Service;
@Service // 表示当前类是Spring管理的一个Bean
// @Scope("singleton") 默认为Singleton,所以注释掉
public class DemoSingletonService {
}
②. 编写Prototype的Bean
package com.eleven.scope1;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
@Service // 表示当前类是Spring管理的一个Bean
@Scope("prototype") // 声明scope为prototype
public class DemoPrototypeService {
}
③. 配置类
package com.eleven.scope1;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration // 声明当前类是一个配置类
@ComponentScan("com.eleven.scope1") // 自动扫描包下面的所有配置
public class ScopeConfig {
}
④.运行
package com.eleven.scope1;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
// 声明AnnotationConfigApplicationContext是Spring管理的一个Bean,将ScopeConfig注入进去
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ScopeConfig.class);
// 获取DemoSingletonService声明的Bean
DemoSingletonService s1 = context.getBean(DemoSingletonService.class);
DemoSingletonService s2 = context.getBean(DemoSingletonService.class);
DemoPrototypeService p1 = context.getBean(DemoPrototypeService.class);
DemoPrototypeService p2 = context.getBean(DemoPrototypeService.class);
System.out.println("Singleton:s1和s2是否相等:" + s1.equals(s2));
System.out.println("Prototype:p1和p2是否相等:" + p1.equals(p2));
context.close();
}
}
5.输出
Singleton:s1和s2是否相等:true
Prototype:p1和p2是否相等:false
二、Profile
1. 介绍
Profile表示可以在不同环境下使用不同的配置。
2. 需求
通过使用Profile注解,来配置生产/开发环境。
3. 示例
①. 示例Bean
package com.eleven.profile;
public class DemoBean {
private String content;
public DemoBean(String context) {
super();
this.content = context;
}
/** get/set方法 */
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
②. Profile配置
package com.eleven.profile;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Configuration // 声明当前类是一个配置类
public class ProfileConfig {
@Bean // 表示当前类的返回值就是一个Bean
@Profile("dev")
public DemoBean devDemoBean() {
return new DemoBean("开发环境");
}
@Bean
@Profile("prod")
public DemoBean prodDemoBean() {
return new DemoBean("生产环境");
}
}
③. 运行
package com.eleven.profile;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
// 使用AnnotationConfigApplicationContext作为Spring的容器
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
// 通过设定Environment的ActiveProfiles来设定当前context的配置环境
context.getEnvironment().setActiveProfiles("prod");
// 先将活动的Profile设置为Prod
// context.getEnvironment().setActiveProfiles("dev"); // 表示开发环境
context.register(ProfileConfig.class);
// 注册Bean的配置类
context.refresh();
// 刷新容器
// 获得DemoBean声明的Bean
DemoBean demoBean = context.getBean(DemoBean.class);
System.out.println(demoBean.getContent());
context.close();
}
}
④. 输出
生产环境
三、事件(Application Event)
1. 介绍
Spring的事件为Bean和Bean之间的消息通信提供了支持。
当一个Bean处理完一个任务之后,希望能够被其它Bean知道并作出相应的处理,这时,我们就需要让其它Bean监听当前Bean所发送的事件。
2. 需求
- 自定义事件,集成ApplicationEvent。
- 定义事件监听器,实现ApplicationListener。
- 使用容器发布事件。
3. 示例
①.自定义事件
package com.eleven.event;
import org.springframework.context.ApplicationEvent;
public class DemoEvent extends ApplicationEvent {
private static final long serialVersionUID = 1L;
private String msg;
/** get/set **/
public DemoEvent(Object source, String msg) {
super(source);
this.msg = msg;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
②.定义事件监听器
package com.eleven.event;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
@Component // 将普通的pojo对象实例化到Spring容器中
public class DemoListener implements ApplicationListener<DemoEvent> {
// 实现了ApplicationListener接口,并指定监听事件的类型
@Override
public void onApplicationEvent(DemoEvent event) {
// 使用onApplicationEvent方法对消息进行接收处理
String msg = event.getMsg();
System.out.println("我(bean-demoListener)接收到了bean-demoPublisher发布的消息:" + msg);
}
}
③.使用容器发布事件
package com.eleven.event;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class DemoPublisher {
@Autowired // 将ApplicationContext注入到当前类中
ApplicationContext applicationContext;
// 注入ApplicationContext用来发布事件
public void publish(String msg) {
applicationContext.publishEvent(new DemoEvent(this, msg));
// 使用ApplicationContext的PublishEvent方法来发布
}
}
④.配置类
package com.eleven.event;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration // 声明当前是一个配置类
@ComponentScan("com.eleven.event") // 自动扫描包下面所以的配置
public class EventConfig {
}
⑤. 运行
package com.eleven.event;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
// 将AnnotationConfigApplicationContext作为Spring的容器,并将参数配置进去
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(EventConfig.class);
// 获得DemoPublisher的声明Bean
DemoPublisher demoPublisher = context.getBean(DemoPublisher.class);
// 发布消息
demoPublisher.publish("Hello Application Event");
context.close();
}
}
⑥. 输出
我(bean-demoListener)接收到了bean-demoPublisher发布的消息:Hello Application Event
网友评论