我正在使用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);
}
}
但我无法让它发挥作用。有人能帮助我吗?
答案 0 :(得分:10)
尝试使用ClassPathXmlApplicationContext
它是一个独立的XML应用程序上下文,从类路径获取上下文定义文件,将普通路径解释为包含包路径的类路径资源名称(例如“mypackage / myresource.txt”)。
对于测试工具以及对JAR中嵌入的应用程序上下文非常有用。
您可以这样做:
创建一个包含以下内容的Test类:
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的bean应用程序配置文件:
<?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
| |--- ...
| |--- ...
|-- ....
在您的清单文件中,您将拥有此功能(使用尾随空白行):
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
P.S。您不必将Spring jar内容包含在您自己的jar中。运行应用程序时,可以在类路径中使用它们。因为你提到了一个罐子,我把它们放在那里。基本上这就是你所需要的:
test.jar --- com
| |--- test
| |--- appConfig.xml
| |--- Test.class
|
|-- META-INF
|--- MANIFEST.MF
答案 1 :(得分:10)
提供你的jar在classpath;您可以使用import
从jar导入bean定义<import resource="classpath:/path-to.xml"/>
答案 2 :(得分:2)
为什么不使用ClasspathXmlApplicationContext并使用类路径相对路径加载它们?
答案 3 :(得分:1)
我想您要将应用程序作为java -jar myapp.jar
在这种情况下,请使用方法main
在班级中使用班级ClassPathXmlApplicationContext。
public static void main( String[] args ) {
String config[] = { "spring-beans.xml" };
ApplicationContext ctx = new ClassPathXmlApplicationContext(config);
DataSource ds = (DataSource) ctx.getBean("dataSource", DataSource.class);
}
尝试实现自己的ApplicationContext是一个糟糕的主意。这是太多的工作和太多的错误空间。
答案 4 :(得分:0)
此link可能会对您有所帮助。我目前无法检查,但我觉得你有同样的问题。