【问题标题】:How to detect application type in Java code如何检测 Java 代码中的应用程序类型
【发布时间】:2011-09-20 20:18:35
【问题描述】:

假设我们有一个 java 包。这个包可以在任何地方使用。然而,这个包中有一些代码是上下文相关的。例如,如果使用此包的应用程序是 Web 应用程序,我们需要通过调用函数来执行某些任务,而如果应用程序是控制台应用程序,则通过调用相同的函数来执行其他任务。

这是我的问题:

在 java 中有什么方法可以在代码中检测应用程序是作为 Web 应用程序还是控制台运行的? 感谢您的帮助:)

作为一个真实的示例,我们加载属性文件的方式对于 Web 和控制台应用程序是不同的。

对于 Web 应用程序,我们可能使用 this.getClass().getClassLoader().getResourceAsStream(url),对于控制台应用程序,我们使用 new FileInputStream(physical path)

【问题讨论】:

    标签: java web-applications jakarta-ee java-me console


    【解决方案1】:

    在某处设置构建属性可能比尝试检测您的应用程序类型更好,因为我认为没有可靠的方法来做到这一点。

    此外,您不应尝试检测应用程序类型,因为根据现代架构原则,您的视图层(Web、桌面或控制台)应该可以轻松互换。


    回应您的最后评论。

    正如用户 384706 所说,DI 是 IMO 的正确选择。 我将举一个spring的例子。

    在您的控制台和 Web 应用程序部件中,您可以拥有:

    public class WebOrConsoleServiceImpl {
    
        private PropertyProvider propertyProvider = new NullPropertyProvider();
    
        // and
    
        public void setPropertyProvider(PropertyProvider impl) {
            this.propertyProvider = impl;
        }
    
        // and in your service logic
    
        public void logic() {
    
            final Properties props = propertyProvider.loadProperties();
            // do stuff            
        }
    }
    

    您的loadProperties() 方法将在您的PropertyProvider 的不同实现中被覆盖。

    在您的春季环境中,您可以拥有:

    <bean id="consolePropertyProvider" class="com.company.ConsolePropertyProvider"/>
    
    <bean id="myConsoleService" class="com.company.MyConsoleService">
        <property name="propertyProvider" ref="consolePropertyProvider" />
    </bean>
    

    你的WebServiceWebPropertyProvider 的同一对bean 定义。

    【讨论】:

    • 我希望拥有相同的代码,但它不起作用。我提出的一个关于加载属性的例子是我的问题之一。如果我知道应用程序类型,那么我可以输入正确的代码,否则我不知道该怎么做:(
    • 你不能在某处设置构建属性吗?你如何建立你的项目?蚂蚁?行家?用手 ?无论如何你应该有一些构建文件?在该文件中,您可以添加类似 deployment.type=[web|console|desktop] 的内容,然后根据您的部署更改该值。这是检测应用类型 IMO 的最可靠方法。
    • 同一个项目。不能那样做!
    • 所以你为两个部署构建一次?
    • 我们设计了一些 Web 部件(不确定它是否是个好名字),用于我们的 Web 应用程序。有一些测试用例和应用程序使用相同的代码和逻辑来执行某些任务——所有这些任务和测试都作为控制台应用程序运行。我们本可以复制代码以便将它们作为单独的项目,但如您所知,复制只会让人头疼。另一方面,我们无法添加构建参数,因为 Web 应用程序已经完成并正在使用中(我们无法更改其代码以消化新设置)。我希望有像 .NET 这样的简单方法!
    【解决方案2】:

    只需使用dependency injection
    只需放置所有适当的参数以通过设置器配置您的库,然后让容器或应用程序使用 DI 相应地配置它。
    所以你不需要任何检查哪个恕我直言是一种不好的方法

    【讨论】:

    • 为了避免硬编码,我不能这样做。依赖注入很好,但如果您不需要经常更改设置。
    【解决方案3】:
    1. J2EE 方式。如果您的包用于 Web 应用程序,那么我假设您在 J2EE 容器中,您可以在部署时在命名中添加 Reference。您还可以注册一个 MDB,它可以侦听对此引用的更改并在运行时修改代码的行为。甜蜜对吧?

    2. 传递调用者上下文的其他标准方法是通过参数化工厂或属性。

    3. 一种非标准方式 - 有趣的是 get the stack trace 并查找调用者是谁或查找 j2ee 上下文等。

    【讨论】:

    • 将尝试#3。听起来可行,但不确定它是否可靠:D thnx
    • 没有。 3 绝对不可靠,因为您事先不知道调用者可能是谁,但是,它肯定是可行的调用 Thread.currentThread().getStackTrace() 然后遍历它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-15
    • 1970-01-01
    • 1970-01-01
    • 2011-02-20
    • 2021-03-31
    相关资源
    最近更新 更多