Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/398.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring@Repository最佳实践_Java_Multithreading_Spring_Spring Mvc - Fatal编程技术网

Java Spring@Repository最佳实践

Java Spring@Repository最佳实践,java,multithreading,spring,spring-mvc,Java,Multithreading,Spring,Spring Mvc,上下文:Web应用程序 我以前没有使用过Spring,但是根据Spring文档,所有bean都是单例的,除非我们声明它们为原型 不使用弹簧: 通常,当有对业务/服务层的调用时,我会实例化新的DAO。 如果它是RESTfull服务,我将实例化几乎所有依赖于调用的对象 带弹簧: 我可以用@Repository注释数据访问类,也可以对服务层类使用@Service 因此,默认情况下,带有上述注释的类是singleton。 有一个@Scope注释,我们可以将它们声明为原型,但似乎没有人这样做 没

上下文:Web应用程序

我以前没有使用过Spring,但是根据Spring文档,所有bean都是
单例的
,除非我们声明它们为
原型

  • 不使用弹簧:
通常,当有对业务/服务层的调用时,我会实例化新的DAO。 如果它是RESTfull服务,我将实例化几乎所有依赖于调用的对象

  • 带弹簧:
我可以用
@Repository
注释数据访问类,也可以对服务层类使用
@Service

因此,默认情况下,带有上述注释的类是
singleton
。 有一个
@Scope
注释,我们可以将它们声明为原型,但似乎没有人这样做

  • 没有弹簧:
    newobject()每次
  • 带弹簧:
    singleton
我的问题是,

  • 我以前使用的方法(每次创建新实例)不正确
  • 如果
    @Repository
    singleton
    ,那么当没有解决这样的问题时,它如何处理线程安全?(假设它是由spring代理完成的)
  • 最佳实践是什么,
    @Repository
    就足够了,还是添加
    @Scope('prototype')
    更好
  • 我没有看到任何人将
    @Scope('prototype')
    @Repository
    一起使用(根据教程、博客等)。有一个众所周知的原因吗
  • 如果我的DAO类被多个非常频繁的线程访问会怎么样?(这是我最关心的)
  • 谢谢

  • 不,但是单元测试要困难得多,这就是依赖注入的全部内容。通过在服务中注入DAO,您可以在测试期间通过注入模拟DAO轻松地对服务进行单元测试。如果服务创建自己的DAO,这是不可能的

  • 除了在启动时初始化的线程安全实体管理器、会话工厂或JDBC模板之外,存储库通常是完全无状态的,因此并发调用不是问题:它是线程安全的

  • 存储库没有理由成为原型。将原型DAO注入到单例服务中仍然会导致同时调用每个原型

  • 没有理由这么做

  • 没问题:如果编码正确,它应该是线程安全的


  • Spring不会为您处理并发问题。这不是故意的。它所做的只是让您控制创建实例的数量,以便您的应用程序能够正常工作

    单例作用域(显而易见)将只创建给定bean的一个实例,并将其传递给所有依赖对象

    每个依赖对象的原型范围将创建自己的实例,而不是在其他对象之间共享

    对于DAO对象,不太可能需要多个实例来与数据库通信。所以通常使用单例。

    你是对的,在春天的世界里,大多数bean都是单例的

  • 我以前使用的方法(每次创建新实例)不正确
  • 这是正确的,因为它的工作。问题是,您在每个请求上实例化一个新的DAO实例——在某些情况下可能会很昂贵,而且无论如何也没有任何意义——为什么需要一堆DAO实例? 另一方面,Spring不仅创建了一个单例,还将DAO注入到服务或其他DAO的e.t.c中。也就是说,它为您做了很多工作

  • 如果@Repository是单例的,那么当没有解决这样的问题时,它如何处理线程安全?(假设它是由spring代理完成的)
  • 在编写@Repository bean时,通常会在其中注入一个数据源或EntityManager。getConnection()方法应该是线程安全的。关于EntityManager,Spring将注入一个代理,该代理对于不同的线程表现不同,即不同的线程不会共享同一个JPA会话

  • 最佳实践是什么,@Repository就足够了,还是添加@Scope('prototype')更好
  • 最佳实践(或者说是最广泛的方法)是只使用@Repository

  • 我没有看到任何人将@Scope(“prototype”)与@Repository一起使用(根据教程、博客等)。有一个众所周知的原因吗
  • 原因是创建@Repository bean的多个实例没有任何好处

  • 如果我的DAO类被多个非常频繁的线程访问会怎么样?(这是我最关心的)

  • 在这里,singleton比为每个请求创建一个新对象要好。只需避免冗余同步,这样您的线程就不会在某些监视器上阻塞

    使用@Repository注释的组件应该是单例的,因为它在整个生命周期中不会有多个/不同的状态。是,它可以保持的唯一状态是连接对象,它将在创建对象期间只设置一次。它将包含与数据存储对话的逻辑/方法,每个方法将获取/返回所需的数据对象。因此,不需要有多个存储库实例。

    非常感谢您给出了清晰的答案。你说的“避免冗余同步”到底是什么意思?我没有在DAO中定义任何同步方法或块。