Spring Scope

这篇具有很好参考价值的文章主要介绍了Spring Scope。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Spring中五种 Scope域

  • singleton,容器启动时创建(未设置延迟),容器关闭时销毁【单例】
  • prototype,每次使用时创建,不会自动销毁,需要调用 DefaultListableBeanFactory.destroyBean(bean) 销毁【原型】
  • request,每次请求用到此 bean 时创建,请求结束时销毁(每次请求来都会创建一个request域对象放到web request域当中,请求结束会被销毁)
  • session,每个会话用到此 bean 时创建,会话结束时销毁(会话创建时会把session对象创建出来放入web session中,会话结束时销毁,会话有默认销毁时间可以设置,长时间不访问自动销毁)
  • application,web 容器用到此 bean 时创建,容器停止时销毁(ServletContext创建后,首次用bean将其放入ServletContext中,销毁Spring未实现)

单例Bean注入其他Scope Bean不做处理,会出现Scope生效的情况,需要在注入bean对象上添加@Lazy注解

演示:

不同scope域的bean

@Scope("application")
@Component
public class BeanForApplication {
    private static final Logger log = LoggerFactory.getLogger(BeanForApplication.class);

    @PreDestroy
    public void destroy() {
        log.debug("destroy");
    }
}

@Scope("session")
@Component
public class BeanForSession {
    private static final Logger log = LoggerFactory.getLogger(BeanForSession.class);

    @PreDestroy
    public void destroy() {
        log.debug("destroy");
    }
}

@Scope("request")
@Component
public class BeanForRequest {
    private static final Logger log = LoggerFactory.getLogger(BeanForRequest.class);

    @PreDestroy
    public void destroy() {
        log.debug("destroy");
    }

}
@RestController
public class MyController {
    
    @Lazy
    @Autowired
    private BeanForRequest beanForRequest;

    @Lazy
    @Autowired
    private BeanForSession beanForSession;

    @Lazy
    @Autowired
    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;
    }
}

分析 - singleton 注入其它 scope 失效

以单例注入多例为例

有一个单例对象 E

@Component
public class E {
    @Autowired
    private F1 f1;

    public F1 getF1() {
        return f1;
    }
}

要注入的对象 F1 期望是多例

@Component
@Scope("prototype")
public class F1 {
    private static final Logger log = LoggerFactory.getLogger(F.class);

    public F1() {
        log.info("F1()");
    }
}

测试:

   E e = context.getBean(E.class);
   log.debug("{}", e.getF1());
   log.debug("{}", e.getF1());

输出:

com.lkl.spring.chapter8.sub.F1@72d1ad2e
com.lkl.spring.chapter8.sub.F1@72d1ad2e

发现它们是同一个对象,而不是期望的多例对象

对于单例对象来讲,依赖注入仅发生了一次,后续再没有用到多例的 F1,因此 E 用的始终是第一次依赖注入的 F

解决

  • 仍然使用 @Lazy 生成代理
  • 代理对象虽然还是同一个,但当每次使用代理对象的任意方法时,由代理创建新的 f 对象
@Component
public class E {

    @Autowired
    @Lazy
    public void setF(F f) {
        this.f = f;
        log.info("setF(F f) {}", f.getClass());
    }

    // ...
}

注意

  • @Lazy 也可以加在成员变量上,但加在 set 方法上的目的是可以观察输出,加在成员变量上就不行了
  • @Autowired 加在 set 方法的目的类似
        E e = context.getBean(E.class);
        log.debug("{}", e.getF1().getClass());
        log.debug("{}", e.getF1());
        log.debug("{}", e.getF1());

输出:

class com.lkl.spring.chapter8.sub.F1$$EnhancerBySpringCGLIB$$278636ac
com.lkl.spring.chapter8.sub.F1@9597028
com.lkl.spring.chapter8.sub.F1@4efbca5a

f 对象的类型是代理类型

解决方法

  1. 单例注入其它 scope 的四种解决方法

    • @Lazy
    • @Scope(value = “prototype”, proxyMode = ScopedProxyMode.TARGET_CLASS)

    Spring Scope,spring,spring,java

    • ObjectFactory
    • ApplicationContext
  2. 解决方法虽然不同,但理念上殊途同归: 都是推迟其它 scope bean 的获取

@Component
public class E {

    // 方法一
    @Lazy
    @Autowired
    private F1 f1;

    // 方法二
    @Autowired
    private F2 f2;

    // 方法三
    @Autowired
    private ObjectFactory<F3> f3;

    // 方法四
    @Autowired
    private ApplicationContext context;

    public F1 getF1() {
        return f1;
    }

    public F2 getF2() {
        return f2;
    }

    public F3 getF3() {
        return f3.getObject();
    }

    public F4 getF4() {
        return context.getBean(F4.class);
    }
}

前两个使用代理对象解决

第三种通过对象工厂,通过对象工厂获取对象,工厂可以识别对象多例类型

最后一种,直接通过ApplicationContext容器获取多例对象

使用代理对象会有点性能损耗,后面两种方法会好些文章来源地址https://www.toymoban.com/news/detail-576354.html

到了这里,关于Spring Scope的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java Spring和Spring集成Mybatis

    1.Spring 2.Spring 集成Mybatis 1.Spring 特性 IOC :控制反转 AOP :面向切面 Spring 组成部分 在SMM中起到的作用(粘合剂) Spring 理念 OOP 核心思想【万物皆对象】 Spring 核心思想【万物皆Bean组件】 Spring 优势 低侵入式 独立于应用服务器 低耦合度 面向切面(集中式处理) 与第三方框架

    2024年02月16日
    浏览(45)
  • 【Spring】Spring基础知识 Java开发必看

    🚀欢迎来到本文🚀 🍉个人简介:陈童学哦,目前专攻C/C++、Python、Java等方向,一个正在慢慢前行的普通人。 🏀系列专栏:陈童学的日记 💡其他专栏:C++STL、蓝桥杯,喜欢OJ的小伙伴可以看一手 🎁希望各位→点赞👍 + 收藏⭐️ + 留言📝 ​ ⛱️学习应使你快乐!望与诸君

    2024年02月13日
    浏览(44)
  • 网页版Java(Spring/Spring Boot/Spring MVC)五子棋项目(四)对战模块

    匹配成功返回数据 1. message消息类别 2. ok 3. reson 4. 房间id 5. 双方id 6.白色玩家 一个类记录房间中的信息(房间id,两个用户id,是否为白棋) 信息提示框 处理匹配API 初始化游戏(棋盘,下一个棋子,接受棋子处理响应,判断是否结束) 1. 客户端连接到游戏房间后, 服务器返回

    2024年02月13日
    浏览(52)
  • spring框架,以及和spring框架相关的Java面试题和spring ioc的注入方式

    目录 一.spring来源,以及介绍 1.spring诞生的背景 2.spring框架 介绍 3.spring框架在使用中的优点以及不足 3.1优点  3.2不足 3.3总结 4.为什么要使用spring  二.将spring框架部署在IDEA中  1.替换pom.xml  2.构建spring所需要的xml文件 三.spring的三种注入方式 0.定义需要的类,方法 1.方法注入

    2024年02月12日
    浏览(51)
  • 初级 - 若依框架 - Java Spring/Spring Boot 项目理解记录

    一般情况下,我们创建对象都是 类名 + 类引用名 = new 类名() 但是如果是不想要 等于号后面的对象实例化操作,那么可以使用 @Autowired 注解,当然这是在使用 Spring 时,才能这样,不然一般情况下,也没法用这个注解。用了这个 @Autowired 注解,会让 Spring 自动帮你托管这个对象

    2024年02月16日
    浏览(52)
  • 探索Java中最常用的框架:Spring、Spring MVC、Spring Boot、MyBatis和Netty

    🎉欢迎来到Java面试技巧专栏~探索Java中最常用的框架:Spring、Spring MVC、Spring Boot、MyBatis和Netty ☆* o(≧▽≦)o *☆嗨~我是IT·陈寒🍹 ✨博客主页:IT·陈寒的博客 🎈该系列文章专栏:Java面试技巧 📜其他专栏:Java学习路线 Java面试技巧 Java实战项目 AIGC人工智能 数据结构学习

    2024年02月08日
    浏览(59)
  • 企业电子招标采购系统源码java 版本 Spring Cloud + Spring Boot

       项目说明 随着公司的快速发展,企业人员和经营规模不断壮大,公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境,最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范,以及审计监督要求;通过电子化

    2024年02月11日
    浏览(66)
  • Java后端07(Spring)

    ​涉及的设计模式:单例模式,简单工厂模式,代理模式,观察者模式,反射,注解。。。。。 ​在传统模式下,对象的创建和赋值,都是由开发者自己手动完成,事实情况下,开发者只关心如何获取赋值好的对象,但是并不希望自己手动进行创建对象和赋值的事情(sprin

    2024年02月13日
    浏览(36)
  • Java # Spring(2)

    编程式事物:代码中硬编码(不推荐使用) 声明式事物:配置文件中配置(推荐使用) 分类: 基于xml的声明式事物 基于注解的声明式事物 ISOLATION_DEFAULT:使用后端数据库默认的隔离级别 Mysql默认采用的REPEATABLE_READ隔离级别 Oracle默认采用的READ_COMMITTED隔离级别 ISOLATION_READ_U

    2024年02月13日
    浏览(34)
  • 【Java】Spring框架介绍

    人不走空                                                                        目录       🌈个人主页:人不走空       💖系列专栏:算法专题 ⏰诗词歌赋:斯是陋室,惟吾德馨 1. Spring框架的核心理念 1. 轻量级和非侵入性 1.1.1 轻量级设计 1.1.2 非侵入性的

    2024年02月21日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包