java - 从调用者获取 ClassLoader 对象

标签 java reflection java-8 classloader stack-trace

我使用 Java 中的 ResourceBundles 实现了插件机制和语言包。

如果我想从核心程序(而不是插件)获取ResourceBundle,它工作得很好。

问题是我想添加创建插件中的 ResourceBundle 的可能性,并且仅在插件内工作。

插件使用URLClassLoaderReflections加载。我无法从翻译类访问(我不想)插件 ClassLoader。 因此,程序加载插件并稍后执行插件内的方法(插件不在类路径中),并且该插件执行翻译方法。

为了实现这一点,我想从调用方法中获取 ClassLoader 对象。

类似于 thisthis可能有用,但我没有找到获取类/类加载器而不是类名称的方法。

我以为我可以使用 Stacktrace 来获取调用方法的 ClassLoader,但我只能使用 .getClassName 获取名称,而不能使用 Class ClassLoader 调用者的对象。

这就是我所拥有的:

翻译

public static String translate(Locale locale,String s) {
    for (ResourceBundle bundle : getResourceBundles(locale/*,Thread.currentThread().getStackTrace()[1].getClassLoader();*/)) {
        try {
            return bundle.getString(s);
        }catch (MissingResourceException e) {
            //ignore/next iteration
        }
    }
    return s;
}

获取资源包

private static Set<ResourceBundle> getResourceBundles(Locale locale,ClassLoader... loaders){
    Set<ResourceBundle> bundles=new HashSet<>();
    bundles.add(ResourceBundle.getBundle(BASE_NAME,locale,MyClass.class.getClassLoader()));
    for (ClassLoader loader : loaders) {
        ResourceBundle pluginBundle=getResourceBundle(g,loader);
        if (pluginBundle!=null) {
            bundles.add(pluginBundle);
        }
    }
    return bundles;
}

最佳答案

我认为这种反复试验的方法不是一个好主意。也不是为每个字符串重新获取所有包。与仅让插件读取其 bundle 并调用 getString 的替代方案相比,该翻译服务似乎并没有增加任何值(value)。就其而言,至少没有一个可以证明代码的开销和复杂性的值。

自标ResourceBundle.getBundle方法确实已经考虑了调用者的上下文,当放置在插件中并调用 getString 时,字段声明和获取表达式将是一个简单的单行代码。在它上面,并不比调用翻译服务的方法复杂。

为了完整起见,从 Java 9 开始可以以标准方式获取调用者类。然后,您可以这样做

private static final StackWalker STACK_WALKER
    = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);

public static String translate(Locale locale, String s) {
    for(ResourceBundle bundle: getResourceBundles(locale,
                                   STACK_WALKER.getCallerClass().getClassLoader())) {
        try {
            return bundle.getString(s);
        }catch (MissingResourceException e) {
            //ignore/next iteration
        }
    }
    return s;
}

关于java - 从调用者获取 ClassLoader 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56636265/

相关文章:

Java 8可选如何定义NullPointerException的错误消息

java - 关闭流而不将其分配给变量 [Java]

java - 可包裹 : Creating an instance of creator and implementing methods inline - CREATOR is an interface?

java - 使用输入字符串生成对象和函数反射

c# - 有可能通过反射(reflection)来做到这一点吗?

javascript - 如何在添加即时特定私有(private)值时自动包装共享对象以别名现有功能

java - Vowpal Wabbit 执行而不写入磁盘

java - SCJP-- 考试问题

java - JPA - 如何在不构造父对象的情况下构造 ManyToOne 关系的子对象

java - 掌握 web.xml 在所有 webapp 项目中使用