Spring Beanアノテーション
1. 概要
この記事では、さまざまなタイプのBeanを定義するために使用されるほとんどのcommon Spring bean annotationsについて説明します。
SpringコンテナでBeanを設定する方法はいくつかあります。 XML構成を使用して宣言できます。 構成クラスの@Beanアノテーションを使用してBeanを宣言できます。
または、org.springframework.stereotypeパッケージのアノテーションの1つでクラスをマークし、残りをコンポーネントのスキャンに任せることもできます。
2. コンポーネントスキャン
コンポーネントのスキャンが有効な場合、SpringはパッケージのBeanを自動的にスキャンできます。
@ComponentScanは、どのpackages to scan for classes with annotation configurationを構成します。 basePackagesまたはvalue引数のいずれかを使用して基本パッケージ名を直接指定できます(valueはbasePackagesのエイリアスです)。
@Configuration
@ComponentScan(basePackages = "com.example.annotations")
class VehicleFactoryConfig {}
また、basePackageClasses引数を使用して、基本パッケージ内のクラスを指すことができます。
@Configuration
@ComponentScan(basePackageClasses = VehicleFactoryConfig.class)
class VehicleFactoryConfig {}
両方の引数は配列であるため、それぞれに複数のパッケージを提供できます。
引数が指定されていない場合、スキャンは@ComponentScanアノテーション付きクラスが存在する同じパッケージから行われます。
@ComponentScanは、Java 8の繰り返しアノテーション機能を利用します。つまり、クラスに複数回マークを付けることができます。
@Configuration
@ComponentScan(basePackages = "com.example.annotations")
@ComponentScan(basePackageClasses = VehicleFactoryConfig.class)
class VehicleFactoryConfig {}
または、@ComponentScansを使用して、複数の@ComponentScan構成を指定することもできます。
@Configuration
@ComponentScans({
@ComponentScan(basePackages = "com.example.annotations"),
@ComponentScan(basePackageClasses = VehicleFactoryConfig.class)
})
class VehicleFactoryConfig {}
using XML configurationの場合、コンポーネントスキャンの構成も同様に簡単です。
3. @Component
@Componentはクラスレベルの注釈です。 コンポーネントスキャン中、Spring Framework automatically detects classes annotated with @Component。
例えば:
@Component
class CarUtility {
// ...
}
デフォルトでは、このクラスのBeanインスタンスは、小文字のイニシャルを持つクラス名と同じ名前を持っています。 さらに、このアノテーションのオプションのvalue引数を使用して、別の名前を指定できます。
@Repository、@Service、@Configuration、および@Controllerはすべて@Componentのメタアノテーションであるため、これらは同じBean命名動作を共有します。 また、Springはコンポーネントのスキャンプロセス中にそれらを自動的に選択します。
4. @Repository
DAOまたはリポジトリクラスは通常、アプリケーションのデータベースアクセス層を表し、@Repository:で注釈を付ける必要があります。
@Repository
class VehicleRepository {
// ...
}
このアノテーションを使用する利点の1つは、it has automatic persistence exception translation enabledです。 Hibernateなどの永続性フレームワークを使用する場合、@Repositoryで注釈が付けられたクラス内でスローされたネイティブ例外は、SpringのDataAccessExeptionのサブクラスに自動的に変換されます。
To enable exception translation、独自のPersistenceExceptionTranslationPostProcessorBeanを宣言する必要があります。
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
ほとんどの場合、Springは上記の手順を自動的に実行することに注意してください。
または、XML構成を介して:
5. @Service
通常、アプリケーションのbusiness logicはサービス層内に存在するため、@Serviceアノテーションを使用して、クラスがその層に属していることを示します。
@Service
public class VehicleService {
// ...
}
6. @Controller
@Controllerは、このクラスがcontroller in Spring MVCとして機能することをSpringFrameworkに通知するクラスレベルのアノテーションです。
@Controller
public class VehicleController {
// ...
}
7. @Configuration
Configurationクラスは、@Beanで注釈を付けたcontain bean definition methodsを使用できます。
@Configuration
class VehicleFactoryConfig {
@Bean
Engine engine() {
return new Engine();
}
}
8. ステレオタイプの注釈とAOP
Springステレオタイプアノテーションを使用すると、特定のステレオタイプを持つすべてのクラスを対象とするポイントカットを簡単に作成できます。
たとえば、DAO層からメソッドの実行時間を測定したいとします。 @Repositoryのステレオタイプを利用して、(AspectJアノテーションを使用して)次のアスペクトを作成します。
@Aspect
@Component
public class PerformanceAspect {
@Pointcut("within(@org.springframework.stereotype.Repository *)")
public void repositoryClassMethods() {};
@Around("repositoryClassMethods()")
public Object measureMethodExecutionTime(ProceedingJoinPoint joinPoint)
throws Throwable {
long start = System.nanoTime();
Object returnValue = joinPoint.proceed();
long end = System.nanoTime();
String methodName = joinPoint.getSignature().getName();
System.out.println(
"Execution of " + methodName + " took " +
TimeUnit.NANOSECONDS.toMillis(end - start) + " ms");
return returnValue;
}
}
この例では、@Repositoryアノテーションが付けられたクラスのすべてのメソッドに一致するポイントカットを作成しました。 次に、@Aroundのアドバイスを使用して、そのポイントカットをターゲットにし、インターセプトされたメソッド呼び出しの実行時間を決定しました。
このアプローチを使用して、ロギング、パフォーマンス管理、監査、またはその他の動作を各アプリケーション層に追加できます。
9. 結論
この記事では、Springステレオタイプアノテーションを調べ、それぞれが表すセマンティクスのタイプを学習しました。
また、コンポーネントスキャンを使用して、注釈付きクラスの場所をコンテナに伝える方法も学びました。
最後に、これらの注釈がどのようにlead to a clean, layered designであり、アプリケーションの懸念事項が分離されているかを確認しました。 また、Beanを手動で明示的に定義する必要がなくなるため、構成が小さくなります。
いつものように、例は利用可能なover on GitHubです。