【问题标题】:What is the difference between getDefaultInstance() and getInstance() in Session class?Session 类中的 getDefaultInstance() 和 getInstance() 有什么区别?
【发布时间】:2023-03-21 22:50:02
【问题描述】:

Session.getDefaultInstance(props, authenticator)getInstance(props, authenticator) 有什么区别?一般来说,您什么时候会选择其中一个?

我还阅读了getDefaultInstance(props, authenticator) 上的 Java 文档,但仍然无法清楚地/清楚地找出区别。

希望专家能帮助我更好地理解这一点。

更新:触发询问此问题的实际原因是:我们在基于 Web 的应用程序中的某些地方使用了Session.getDefaultInstance() 方法。有时,它会抛出java.lang.SecurityException: Access to default session denied,在快速谷歌搜索时,它建议改用Session.getInstance() 方法。因此,什么时候会选择一个而不是另一个?

【问题讨论】:

  • download.oracle.com/javaee/6/api/javax/mail/… 此文档可能会帮助您了解差异
  • @org.life.java:我找不到任何区别?你能指出一些具体的句子/段落吗?
  • getInstance():获取一个新的Session对象。 , getDefaultInstance() : 获取默认的 Session 对象。如果尚未设置默认值,则会创建一个新的 Session 对象并将其安装为默认值。
  • @org.life.java:实时,什么时候会选择一个而不是另一个?就我而言,我们有一个基于 Web 的应用程序,并且有一些上下文/位置会触发电子邮件。在这种情况下推荐哪种方法?

标签: java session jakarta-mail


【解决方案1】:

如果你阅读文档,你会看到

获取默认实例 获取默认的 Session 对象。如果尚未设置默认值,则会创建一个新的 Session 对象并将其安装为默认值。

因此,如果一个不存在,则调用 getInstance()

获取实例 获取一个新的 Session 对象。

因此,无论是否已经存在,都会创建一个新的会话对象。

【讨论】:

  • 问这个问题的实际原因在这里解释:我们在我们的基于网络的应用程序中的某些地方使用了Session.getDefaultInstance() 方法。有时,它会抛出java.lang.SecurityException: Access to default session denied,在快速谷歌搜索时,它建议使用Session.getInstance() 方法。这就是我在这里问一个人何时会选择一个而不是另一个的原因?
  • 我能看到使用 defaultinstance 的唯一原因是它可以防止不必要地创建会话的多个实例,但除此之外没有区别。如果您在权限方面遇到问题,那么只需使用 getInstance(),它应该不会给您带来问题。但是,您的应用程序应该将其存储在全局级别,而不是每次需要时都创建一个新实例。
  • @Gnanam,是的,但它使用跨 JVM 的共享实例(在文档中的行之间阅读,说明会话可以跨桌面共享)。因此,这可能就是他收到错误的原因,即它正在使用共享实例并使用错误的凭据访问它。因此,为了防止错误,不使用 getDefaultInstance() 会更安全。
  • 使用 getDefaultInstance 的一个非常重要的副作用是,如果会话已经创建,您传入的属性将被忽略。现有的会话属性不会以任何方式更新,因此如果您要更改任何要使用 getInstance 的属性。
  • 这已包含在JAVAMAIL API FAQ 中。
【解决方案2】:

常见问题解答:https://javaee.github.io/javamail/FAQ#getdefaultinstance

问:什么时候应该使用Session.getDefaultInstance,什么时候应该使用 使用Session.getInstance?

答:几乎所有代码都应该使用Session.getInstance。这 Session.getDefaultInstance 方法首先创建一个新的 Session 使用传递的属性调用它的时间。随后的 调用将返回原始会话并忽略您的任何属性 传入。如果你想创建不同的 Sessions 属性, Session.getDefaultInstance 不会那样做。如果其他一些 同一个 JVM(例如,同一个应用服务器)中的代码已经 使用它们的属性创建了默认会话,您最终可能会 使用他们的 Session 并且您的属性将被忽略。这往往 解释了为什么您的属性设置似乎被忽略了。 始终使用 Session.getInstance 来避免这个问题。

【讨论】:

    【解决方案3】:

    原因 此错误在 javax.mail.Session.java 中的 getDefaultInstance 方法中引发。根据此源代码,当默认会话对象已初始化,但身份验证器实例被更新或更改,或者默认会话对象的类加载器与参数身份验证器不同时,会发生此错误。可能使用 java 邮件的默认会话实例的 java 源代码被重新编译和重新加载,或者重复的 javamail 类库包含在环境的 Classpath 中。 它给出了正确的解决方案

    javax.mail.Session.java file
       public static synchronized Session getDefaultInstance(Properties props,
                                           Authenticator authenticator) {
           if (defaultSession == null)
               defaultSession = new Session(props, authenticator);
           else {
               // have to check whether caller is allowed to see default session
               if (defaultSession.authenticator == authenticator)
                   ;       // either same object or both null, either way OK
               else if (defaultSession.authenticator != null &&
                       authenticator != null &&
                       defaultSession.authenticator.getClass().getClassLoader() ==
                           authenticator.getClass().getClassLoader())
                   ;       // both objects came from the same class loader, OK
               else
                   // anything else is not allowed
                   throw new SecurityException("Access to default session denied");
           }
    
           return defaultSession;
       }
    

    【讨论】:

      【解决方案4】:

      对我来说,使用 getInstance() 而不是 getDefaultInstance() 非常重要。

      因为更改邮件会话属性后,邮件会话仍然存储旧属性。

      所以getDefaultInstance() - 它看起来像单身。

      正如文档所说:

      还要注意,Properties 对象仅在第一次调用此方法时使用,即创建新的 Session 对象时。后续调用返回第一次调用创建的 Session 对象,并忽略传递的 Properties 对象。每次调用该方法时,使用 getInstance 方法获取一个新的 Session 对象。

      【讨论】:

      • 这条关键信息在 getDefaultInstance(Properties, Authenticator) 的文档中,而不是在 getDefaultInstance(Properties) 的文档中。
      猜你喜欢
      • 2014-06-27
      • 1970-01-01
      • 2019-08-25
      • 1970-01-01
      • 2016-02-14
      • 1970-01-01
      • 1970-01-01
      • 2020-06-05
      • 2011-05-06
      相关资源
      最近更新 更多