1

従うべきパラダイムについてアドバイスが必要です。以前、こんな事がありました

package/Instantiator.class

package/instances/GenericInstance.class (abstract)

package/instances/AInstance.class (extends Generic)

package/instances/BInstance.class (extends Generic)

Instantiatorすべてのクラス ファイルのフォルダーを検索しpackage/instances、それぞれをリフレクションでインスタンス化し、すべてのインスタンスで抽象メソッドを呼び出して出力を収集し、DB に保存しました。

ただし、コードを Jar にパッケージ化する必要があります。Java では、jar 内のパッケージ内のすべてのクラス ファイルを検索できないようです (パスが混乱しているように見えるため)。

GenericInstance などの List にすべてのインスタンスを追加すると、Instantiator はクラスのリストを取得できます。

しかし、他の人がそのパッケージにクラスを追加できるようにしたいと思います。それだけです。

ここではどのパターンに従うべきですか?コードのヘルプはありますか? ありがとう!

4

2 に答える 2

1

JDK にはServiceLoader(Java 6+) という組み込みソリューションが 1 つあります。META-INF/servicesただし、ユーザーが実装のリストを含むファイルを作成する必要があります。

基本インターフェースが次の場合package.instances.GenericInstance、ファイルが呼び出されMETA-INF/services/package.instances.GenericInstance、その内容は次のようになります。

path.to.implementation1
path.to.implementation2

など。使用するビルド システムによっては、この種のファイルが自動的に生成される場合があります (maven にはプラグインがあります。こちらを参照してください)。

Java では、jar 内のパッケージ内のすべてのクラス ファイルを検索できないようです。

はい、できます (ただし、それを行うコードは非常に複雑ですURLClassLoader。などを作成する必要があります)。

実行時にすべてのjarがクラスパスにある場合の1つの解決策は、リフレクションのようなものを使用することです(ボーナス:Guavaに依存するため、すべての機能を取得できます)。これには、クラスなどの効率的なフィルターがあり、 「システム」クラスローダー。これも機能する可能性があります。

于 2013-06-14T18:00:20.190 に答える
0

私が発見した私の方法:

try {    

    String jarName = new File(Insantiator.class.getProtectionDomain()    
                                                            .getCodeSource()    
                                                            .getLocation()    
                                                            .getPath())    
                                                            .getName();    
    JarFile jar = new JarFile(jarName);    
    Enumeration<JarEntry> entries = jar.entries();    
    while(entries.hasMoreElements()) {    
        ZipEntry entry = entries.nextElement();    
        String name = entry.getName();    
        if(name.contains("package/instances") && !name.contains("GenericInstance.class") && name.contains(".class")) {    
            name = name.replace("/", ".").replace(".class", "");    
            try {    
                Class theClass = Class.forName(name);    
                GenericInstance instance = (GenericInstance ) theClass.newInstance();    
                instances.add(instance);    
            } catch(InstantiationException | IllegalAccessException | ClassNotFoundException e) {    
                Utilities.writeLog("---- tried: " + name);    
                Utilities.writeLogException(null, e);    
            }    
        }    
    }        

} catch (IOException e) {    
    Utilities.writeLogException(null, e);    
}
于 2013-06-14T19:16:55.280 に答える