是否可以创建指向in的URL?
我试图通过将JPA
配置设置为自动(和可移植)来扩展我的库以集成Swing
和JPA
,并且这意味着以编程方式添加<class>
元素。 (我知道它可以通过Hibernate的AnnotationConfiguration
或EclipseLInk的ServerSession
来完成,但是可移植性)。 我也想避免仅仅为了这个目的而使用Spring
。
我可以随时创建一个persistence.xml
,并使用指定包中的<class>
元素(通过Reflections库)填充它。 当我尝试将这个persistence.xml
提供给JPA
提供者时,问题就开始了。 我能想到的唯一方法就是设置一个URLClassLoader
,但我想不出什么方法不能让我在第一个地方将文件写入磁盘,以获得有效URL
唯一能力。 设置一个通过URL
( localhost:xxxx
)提供文件的套接字似乎......我不知道,邪恶?
有没有人有一个想法,我可以如何解决这个问题? 我知道这听起来像避免使用一个库很多工作,但我只想知道它是否可以完成。
编辑 (尝试更清晰):
动态生成的XML
保存在一个String
对象中。 我不知道如何将它提供给持久性提供者。 另外,我想避免将文件写入磁盘。
为了解决我的问题,持久性提供者只是一个类,它扫描META-INF/persistence.xml
的类路径。 可以使一些实现接受XML
动态创建,但没有通用接口(特别是对于文件的关键部分, <class>
标记)。
我的想法是设置一个自定义的ClassLoader
- 如果你有其他任何我会很感激,我没有设置这个。
我能找到的唯一容易扩展/可配置的是URLClassLoader
。 它适用于URL
对象,我不知道我是否可以创建一个,而无需先将XML写入磁盘。
这就是我设置的方式,但它通过将persistenceXmlFile = new File("META-INF/persistence.xml")
写入磁盘来工作:
Thread.currentThread().setContextClassLoader(
new URLResourceClassLoader(
new URL[] { persistenceXmlFile.toURI().toURL() },
Thread.currentThread().getContextClassLoader()
)
);
URLResourceClassLoader
是URLCLassLoader
的子类,它允许通过重写public Enumeration<URL> findResources(String name)
来查找资源和类。
也许有点晚(4年后),但对于其他正在寻找类似解决方案的用户,您可以使用我创建的URL工厂:
public class InMemoryURLFactory {
public static void main(String... args) throws Exception {
URL url = InMemoryURLFactory.getInstance().build("/this/is/a/test.txt", "This is a test!");
byte[] data = IOUtils.toByteArray(url.openConnection().getInputStream());
// Prints out: This is a test!
System.out.println(new String(data));
}
private final Map<URL, byte[]> contents = new WeakHashMap<>();
private final URLStreamHandler handler = new InMemoryStreamHandler();
private static InMemoryURLFactory instance = null;
public static synchronized InMemoryURLFactory getInstance() {
if(instance == null)
instance = new InMemoryURLFactory();
return instance;
}
private InMemoryURLFactory() {
}
public URL build(String path, String data) {
try {
return build(path, data.getBytes("UTF-8"));
} catch (UnsupportedEncodingException ex) {
throw new RuntimeException(ex);
}
}
public URL build(String path, byte[] data) {
try {
URL url = new URL("memory", "", -1, path, handler);
contents.put(url, data);
return url;
} catch (MalformedURLException ex) {
throw new RuntimeException(ex);
}
}
private class InMemoryStreamHandler extends URLStreamHandler {
@Override
protected URLConnection openConnection(URL u) throws IOException {
if(!u.getProtocol().equals("memory")) {
throw new IOException("Cannot handle protocol: " + u.getProtocol());
}
return new URLConnection(u) {
private byte[] data = null;
@Override
public void connect() throws IOException {
initDataIfNeeded();
checkDataAvailability();
// Protected field from superclass
connected = true;
}
@Override
public long getContentLengthLong() {
initDataIfNeeded();
if(data == null)
return 0;
return data.length;
}
@Override
public InputStream getInputStream() throws IOException {
initDataIfNeeded();
checkDataAvailability();
return new ByteArrayInputStream(data);
}
private void initDataIfNeeded() {
if(data == null)
data = contents.get(u);
}
private void checkDataAvailability() throws IOException {
if(data == null)
throw new IOException("In-memory data cannot be found for: " + u.getPath());
}
};
}
}
}
链接地址: http://www.djcxy.com/p/72473.html