java - jar 文件中的 Spring 上下文

标签 java spring

我正在使用 spring 和 hibernate 在 java 中开发一个桌面应用程序。我想将其打包为可执行 jar,但在从 jar 文件中加载上下文配置 XML 时遇到问题。

我将应用程序打包为一个可运行的 jar 文件,当我运行该 jar 文件时,它告诉我该文件不存在。我知道我应该从一个 jar 文件中加载一个 InputStream,但没有支持它的 ApplicationContext 实现。

我相信我必须编写自己的 InputStreamXmlApplicationContext 并且我已经尝试过这样做。我做了一些研究和一些编码:


import java.io.InputStream;

import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.support.AbstractXmlApplicationContext;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;

public class InputStreamXmlApplicationContext extends AbstractXmlApplicationContext {

    private Resource[] configResources;

    public InputStreamXmlApplicationContext(InputStream in) {
        InputStreamResource resource = new InputStreamResource(in);
        configResources = new InputStreamResource[] {resource};
        setConfigResources(configResources);
        refresh();
    }

    public Resource[] getConfigResources() {
        return configResources;
    }

    public void setConfigResources(Resource[] configResources) {
        this.configResources = configResources;
    }

    protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) {
        beanDefinitionReader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_XSD);
    }
}

但我无法让它工作。有人可以帮我吗?

最佳答案

尝试使用 ClassPathXmlApplicationContext

它是一个独立的 XML 应用程序上下文,从类路径中获取上下文定义文件,将普通路径解释为包含包路径的类路径资源名称(例如“mypackage/myresource.txt”)。

适用于测试工具以及嵌入在 JAR 中的应用程序上下文

你可以这样做:

为自己创建一个包含以下内容的测试类:

package com.test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
  public static void main(String[] args) {
    ClassPathXmlApplicationContext context = new 
           ClassPathXmlApplicationContext("/com/test/appConfig.xml");
    Integer someIntBean = (Integer) context.getBean("testBean");
    System.out.println(someIntBean.intValue()); // prints 100, as you will see later
  }
}

现在创建名为 appConfig.xml 的 beans 应用程序配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
  <bean id="testBean" class="java.lang.Integer">
    <constructor-arg type="int" value="100" />
  </bean>
</beans>

您在一个名为 com.test 的包中创建这些文件,这些文件彼此相邻。将类路径引用添加到您的 spring jar 或将它们一起打包到您自己的单个 jar 文件中,应该如下所示:

test.jar --- com
          |   |--- test
          |          |--- appConfig.xml
          |          |--- Test.class
          |
          |-- META-INF
          |        |--- MANIFEST.MF
          |
          |-- org
          |     |--- springframework 
          |               |--- ...
          |               |--- ...
          |-- ....

在您的 list 文件中,您将拥有以下内容(与尾随空行一起使用):

Main-Class: com.test.Test

就是这样。

当你运行你的文件(双击或java -jar test.jar)你应该看到100 打印在屏幕上。这是我从执行它得到的结果(注意我上面所说的 100 - 在最后一行):

Feb 23, 2011 11:29:18 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@ca2dce: 
display name [org.springframework.context.support.ClassPathXmlApplicationContext@ca2dce]; 
startup date [Wed Feb 23 23:29:18 PST 2011]; root of context hierarchy
Feb 23, 2011 11:29:18 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [com/test/appConfig.xml]
Feb 23, 2011 11:29:20 PM org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory
INFO: Bean factory for application context [org.springframework.context.support.ClassPathXmlApplicationContext@ca2dce]: 
org.springframework.beans.factory.support.DefaultListableBeanFactory@199f91c
Feb 23, 2011 11:29:20 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@199f91c: 
defining beans [testBean]; root of factory hierarchy
100

附:您不必绝对将 Spring jars 内容包含到您自己的 jar 中。运行应用程序时,您可以在类路径中使用它们。既然你提到了一个 jar ,我就这样放了它们。基本上这就是你所需要的:

test.jar --- com
          |   |--- test
          |          |--- appConfig.xml
          |          |--- Test.class
          |
          |-- META-INF
                   |--- MANIFEST.MF

关于java - jar 文件中的 Spring 上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5071622/

相关文章:

java - 如何使用 ByteBuddy 动态扩展具体类

java - 一个 @Configuration 类中的 @Primary bean 不会覆盖在另一个此类中定义和使用的 bean

reactjs - 为什么迁移到 https 会中断客户端和服务器之间的通信?

java - SQLException : fetched column value was truncated when executing while (rs. getNext())

java - 如何通过 RMI 传递输入流

java - 从 Web 服务中的 sun-web.xml 获取上下文根

jquery - Spring MVC Ajax 400错误请求

java - 如何创建 @RequestMapping @PathVariable 以在参数中包含/?

java - 什么是处理在此 Spring Boot 应用程序中实现接口(interface)的不同类列表的智能解决方案?

java - 有没有办法为方法概述静态变量?