Spring中注解Scope代表对象的生命周期,分为五种
singleton:单例模式,当spring创建applicationContext容器的时候,spring会欲初始化所有的该作用域实例,加上lazy-init就可以避免预处理;
prototype:原型模式(多例模式),每次通过getBean获取该bean就会新产生一个实例,创建后spring将不再对其管理;
====下面几种是在web项目下才用到的===
request:搞web的大家都应该明白request的域了吧,就是每次请求都新产生一个实例,和prototype不同就是创建后,接下来的管理,spring依然在监听 给每个http request新建一个bean实例
session:每次会话,同上 给每个http session新建一个bean实例
global session:全局的web域,类似于servlet中的application
spring的controller(service)默认是单例,是singleton所以在controller注解中不允许使用全局变量(注意点)。
下面是自定义Scope:
首先是实现Scope接口,里面的get方法就是注解对象的生成方法当使用注解时Spring会按照get方法去生成,然后去实现 BeanDefinitionRegistryPostProcessor接口里面的postProcessBeanFactory方法中的factory.registerScope("websocket", new WebSocketScope());将该Scope注解注册到Spring容器中,ScopedLifeCircle实现该接口在get(String name, ObjectFactory<?> objectFactory)按照name名称获取不到时用,实现applicationContextWare之后可以利用application.getBean("name"),灵活实现实例的注入。
public class WebSocketScope implements Scope {
public WebSocketScope() {
}
@Override
public Object get(String name, ObjectFactory<?> objectFactory) {
//获取当前websocket 会话的 RequestAttributes, 即beans 的容器
WebSocketRequestAttributes attributes = WebSocketContextHolder.currentRequestAttributes();
if(attributes == null) {
throw new IllegalStateException("No WebSocketRequestAttributes found: ");
}
Object scopedObject = attributes.getAttribute(name);
if (scopedObject == null) {
//如果这个对象还不存在,则通过objectFactory生成一个,然后存入RequestAttributes 中
scopedObject = objectFactory.getObject();
//如果bean 实现了 ScopedLifeCircle, 调用 initScope 实现init
if(scopedObject instanceof ScopedLifeCircle) {
ScopedLifeCircle circle = (ScopedLifeCircle)scopedObject;
circle.initScope();
}
attributes.setAttribute(name, scopedObject);
}
return scopedObject;
}
@Override
public Object remove(String name) {
WebSocketRequestAttributes attributes = WebSocketContextHolder.currentRequestAttributes();
return attributes == null ? null : attributes.remove(name);
}
@Override
public void registerDestructionCallback(String s, Runnable runnable) {
}
@Override
public Object resolveContextualObject(String s) {
return null;
}
@Override
@Nullable
public String getConversationId() {
return null;
}
}
@Component
public class WebSocketRegister implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) throws BeansException {
factory.registerScope("websocket", new WebSocketScope());
}
}
*
* bean 对象的生命周期管理, 只针对我们的websocket 对象 有效
* websocket bean 对象推荐实现这个接口,也可以不实现这个接口
*/
public interface ScopedLifeCircle {
/**
* 创建 websocket 会话时的响应函数
*/
void initScope();
/**
* 关闭会话时的响应函数
*/
void closeScope();
}