Javaが提供するリソースにアクセスするためのAPIでは、URLでリソースの場所を指定できます。Javaが提供するAPIは、さまざまなタイプのURLHandlerを使用して処理しますが、欠点もあり、誰もが低レベルのリソースにアクセスできるわけではありません。たとえば、クラスパスまたはServletContextからリソースにアクセスするための標準のURL実装はありません。特別なURLプレフィックスの新しいハンドラーを登録することは可能ですが(http:などのプレフィックスの既存のハンドラーと同様)、これは通常非常に複雑であり、URLインターフェイスには、指定されたリソースのチェックなど、いくつかの必要な機能がありません。メソッドは存在しますか。そのため、Springはリソースアクセスの抽象化を提供します。Springでは、Resourceインターフェイスを使用して低レベルのリソースにアクセスします。ResourceインターフェイスはSpringで広く使用されていますが、実際の作業でアクセスを許可するための実用的なツールクラスとしても使用できます。リソースがシンプルになります。そのため、この部分については個別に説明します。リソースの定義は次のとおりです。
public interface InputStreamSource {
//查找并加载资源,返回一个从资源中读取的InputStream。每次调用都会返回一个新的InputStream。流的关闭由调用者负责
InputStream getInputStream() throws IOException;
}
public interface Resource extends InputStreamSource {
//判断资源是否存在
boolean exists();
//返回一个布尔值,该值指示此资源是否表示具有开放流的句柄。如果为true,则无法多次读取
//InputStream,必须只读取一次,然后关闭以避免资源泄漏。对于所有常见的资源实现都将为false,
//但InputStreamResource除外。
boolean isOpen();
//返回资源的URL实例
URL getURL() throws IOException;
//返回资源的File实例
File getFile() throws IOException;
//创建一个相对路径的资源
Resource createRelative(String relativePath) throws IOException;
//返回资源名称
String getFilename();
//返回此资源的说明,在使用该资源时用于错误输出。通常表示完全限定的文件名或资源的实际URL
String getDescription();
}
リソースは、Springのリソース(Springのxml構成など)を抽象化したものです。Springで広く使用されています。多くのメソッドがリソースを使用する必要がある場合(ApplicationContextの多くの実装の構築メソッドなど)、パラメータータイプとして表示されます。文字列はコンストラクターにResourceを作成し、Resourceは文字列に基づいてリソースをロードするための適切な実装を選択します。Springがどのようにリソースをロードするかについては後で説明するので、ここでは説明しません。
注意する必要があるのは、Resourceは関数を実装せず、Resourceに使用される可能性のある関数を抽象化するだけであるということです。たとえば、その実装UrlResourceはURLをラップし、ラップされたURLを使用して作業を完了します。さらに、Springは、ほぼすべてのリソースにアクセスするリソース実装を提供します。以下は、リソース実装のクラス図です。
上記のクラスの階層構造図は、URL、クラスパス、コンテキスト、ファイルなどを含むResourceのすべての実装です。以下では、いくつかの実装を紹介します。
UrlResourceはjava.net.URLをカプセル化し、ファイル、HTTP、FTPなど、通常はURLを介してアクセスできる任意のオブジェクトにアクセスするために使用できます。すべてのURLには標準化された文字列表現があるため、指定された文字列に基づいてリソースのタイプを示すことができます。これには、ファイル:ファイルシステムパスへのアクセスに使用、http:httpプロトコルを介したリソースへのアクセスに使用、ftp:ftpを介したリソースへのアクセスなどが含まれます。
ClassPathResourceは、クラスパスから取得する必要があるリソースを表します。スレッドコンテキストクラスローダー、特定のクラスローダー、または特定のクラスを使用してリソースをロードします。クラスパスリソースがファイルシステムに存在する場合、jarに存在し、ファイルシステムに拡張されていない(サーブレットエンジンまたは他の環境を介して)クラスパスリソースではなく、java.io.Fileの解析をサポートします。
FileSystemResourceは、java.io.File操作に基づくリソース実装であり、ファイルおよびURLソリューションをサポートします。
ServletContextResourceは、相対パスをWebアプリケーションのルートディレクトリとして扱うServletContextリソースのリソース実装です。常にストリーミングアクセスとURLアクセスをサポートしますが、Webアプリケーションがアーカイブされ、リソースが実際にファイルシステム上にある場合、java.io.Fileアクセスのみが許可されます。それがファイルシステム内にあるか、JARまたは他の場所(DBなど)から直接アクセスされるか(これは考えられます)は、実際にはサーブレットコンテナに依存します
InputStreamResourceは、特定のInputStreamのリソースの実装です。このメソッドは、適用可能な特定のリソース実装がない場合にのみ使用されます。可能であれば、ByteArrayResourceまたはファイルベースのリソース実装を優先する必要があります。他のリソース実装とは異なり、これは開かれたリソースの記述子であるため、isOpen()からtrueが返されます。したがって、リソース記述子をどこかに保存する必要がある場合、またはストリームを複数回読み取る必要がある場合は、ByteArrayResourceなどの他のリソース実装を使用してください。
ByteArrayResourceこれは、特定のバイト配列に対するResourceの実装です。指定されたバイト配列のByteArrayInputStreamを作成します。これは、任意のバイト配列からコンテンツをロードする場合に非常に便利です。一度しか読み取れないInputStreamResourceを使用する代わりに。
以前、いくつかの異なるリソース実装を紹介しましたが、Springはどのようにリソースをロードしますか?以下では、Springがどのようにリソースをロードするかを紹介します。Springでのリソースの読み込みは、ResourceLoaderインターフェイスとして抽象化されます。これは、次のように定義されているResourceインスタンスを返すgetResourceメソッドを提供します。
public interface ResourceLoader {
Resource getResource(String location);
}
すべてのアプリケーションコンテキストは、ClassPathXmlApplicationContext、FileSystemXmlApplicationContext、WebApplicationContextなどのResourceLoaderインターフェイスを実装します。これらの実装を通じてResourceインスタンスを取得できます。例としてClassPathXmlApplicationContextを使用します。クラス階層図とコードは次のとおりです。
Resource template = ctx.getResource("some/resource/path/myTemplate.txt");
上記のコードでは、ctxがClassPathXmlApplicationContextインスタンスの場合、ClassPathResourceを返します。ctxがFileSystemXmlApplicationContextインスタンスの場合、FileSystemResourceを返します。それが、WebApplicationContextの場合、ServletContextResourceなどを返します。リソースの指定されたリソースのタイプを取得することもでき、対応するタイプのリソース実装が返されます。コードは次のとおりです。
Resource template = ctx.getResource("classpath:some/resource/path/myTemplate.txt");
Resource template = ctx.getResource("file:///some/resource/path/myTemplate.txt");
Resource template = ctx.getResource("http://myhost.com/resource/path/myTemplate.txt");
先ほど、すべてのアプリケーションコンテキストがResourceLoaderを実装し、それを介してResourceLoaderインスタンスを取得できると述べました。さらに、次のように定義されているResourceLoaderAwareインターフェイスを介してResourceLoaderインスタンスを取得することもできます。
public interface ResourceLoaderAware {
void setResourceLoader(ResourceLoader resourceLoader);
}
クラスがResourceLoaderAwareインターフェイスを実装し、クラスがSpringコンテナによって管理されている場合、そのクラスはアプリケーションコンテキストによってResourceLoaderAwareと見なされ、setResourceLoader(ResourceLoader)を呼び出してResourceLoaderインスタンスを提供します。実際、Springの多くの内部実装を使用できます。このプログラムを通じて提供される場合、たとえば、ApplicationContextAwareはApplicationContextインスタンスを提供します。このクラスの使用法はここでは紹介されません。ブログ:SpringでのAwareインターフェイスの使用-ApplicationContextAwareおよびBeanNameAwareを参照できます。
さらに、Beanを介してResourceインスタンスを自動的に挿入することもできます。BeanにResourceタイプのフィールドがある場合、Beanを介してそれを挿入できます。例は次のとおりです。
<bean id="myBean" class="...">
<property name="template" value="some/resource/path/myTemplate.txt"/>
</bean>
上記で構成されたリソースにはプレフィックスがないため、アプリケーションコンテキスト自体がResourceLoaderとして機能し、リソース自体は、コンテキストに応じて、ClassPathResource、FileSystemResource、またはServletContextResourceを介してロードされます。もちろん、特定のタイプを指定することもできます。例は次のとおりです。
<bean id="myBean" class="...">
<property name="template" value="file:///some/resource/path/myTemplate.txt"/>
</bean>
アプリケーションコンテキストコンストラクター(特定のアプリケーションコンテキストタイプ用)は通常、リソース(コンテキスト定義を構成するXMLファイルなど)のロケーションパスとして文字列または文字列の配列を使用します。このようなロケーションパスにプレフィックスがない場合、パスから構築され、Bean定義のロードに使用される特定のリソースタイプは、特定のアプリケーションコンテキストに依存し、適切です。たとえば、次のようにClassPathXmlApplicationContextを作成する場合:
ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/appContext.xml");
上記のメソッドは、クラスパスからリソースをロードしてClassPathResourceを使用しますが、FileSystemXmlApplicationContextを作成すると、ファイルシステムの場所からロードされます。次の例は、現在の作業ディレクトリに関連しています。
ApplicationContext ctx = new FileSystemXmlApplicationContext("conf/appContext.xml");
着信パラメータにプレフィックスまたはURLを追加すると、デフォルトのタイプが上書きされます。たとえば、次の例では、クラスパスからリソースをロードします。
ApplicationContext ctx = new FileSystemXmlApplicationContext("classpath:conf/appContext.xml");
アプリケーションコンテキストコンストラクター値のリソースパスは、ターゲットリソースとの1対1のマッピングを持つ単純なパス(上記のように)にすることも、特別な「classpath *:」プレフィックスや内部Antスタイルを含めることもできます。通常の式(マッチングにはSpringのPathMatcherユーティリティを使用します)。次に、Antスタイルのリソースパスの例を示します。
/WEB-INF/*-context.xml
com/mycompany/**/applicationContext.xml
file:C:/some/path/*-context.xml
classpath:com/mycompany/**/applicationContext.xml