Spring 高级 Scope
介绍
1、在当前版本的 Spring 和 Spring Boot 程序中,支持五种 Scope
- singleton,容器启动时创建(未设置延迟),容器关闭时销毁
- prototype,每次使用时创建,不会自动销毁,需要调用 DefaultListableBeanFactory.destroyBean(bean) 销毁
- request,每次请求用到此 bean 时创建,请求结束时销毁
- session,每个会话用到此 bean 时创建,会话结束时销毁
- application,web 容器用到此 bean 时创建,容器停止时销毁
2、有些文章提到有 globalSession 这一 Scope,也是陈旧的说法,目前 Spring 中已废弃
但要注意,如果在 singleton 注入其它 scope 都会有问题,解决方法
- @Lazy
- @Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
- ObjectFactory
- ApplicationContext.getBean
request, session, application 作用域
1、代码
package com.mangoubiubiu.show.a08; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import javax.annotation.PreDestroy; @Scope("application") @Component @Slf4j public class BeanForApplication { @PreDestroy public void destroy(){ log.info("destroy"); } }
package com.mangoubiubiu.show.a08; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import javax.annotation.PreDestroy; @Scope("request") @Component @Slf4j public class BeanForRequest { @PreDestroy public void destory(){ log.info("destory"); } }
package com.mangoubiubiu.show.a08; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import javax.annotation.PreDestroy; @Scope("session") @Component @Slf4j public class BeanForSession { @PreDestroy public void destroy(){ log.info("destory"); } }
package com.mangoubiubiu.show.a08; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; @RestController public class MyController { @Lazy @Autowired private BeanForRequest beanForRequest; @Autowired @Lazy private BeanForSession beanForSession; @Autowired @Lazy private BeanForApplication beanForApplication; @GetMapping(value = "/test", produces = "text/html") public String test(HttpServletRequest request, HttpSession session) { ServletContext sc = request.getServletContext(); String sb = "<ul>" + "<li>" + "request scope:" + beanForRequest + "</li>" + "<li>" + "session scope:" + beanForSession + "</li>" + "<li>" + "application scope:" + beanForApplication + "</li>" + "</ul>"; return sb; } }
package com.mangoubiubiu.show.a08; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) public class A08Application { public static void main(String[] args) { SpringApplication.run(A08Application.class,args); } }
刷新一下会发现request域对象变了
用另外一个匿名窗口访问发现session域对象变了
重启应用发现application域对象变了