Springで java.util 的なユーティリティクラスを自作し、他のクラスで @Inject
(または @Autowired
)して使う場合、そのクラスに付けるべきアノテーションは主に以下の2つのどちらかです
① @Component
@Component
public class MyUtil {
// ユーティリティメソッドなど
}
一般的なSpring管理Beanとして登録。
他クラスで @Inject
(または @Autowired
) によりDI可能。
このクラスは明示的にSpringに管理させるので、DIの対象にできます。
@Service
(ビジネスロジック寄りの場合)
@Service
public class MyUtil {
// 複雑なロジックなど
}
実際には @Component
と同じくBean登録されますが、意図の明確化として使われます。
ユーティリティクラスが何らかのビジネス処理を支えるものであれば @Service
の方が読み手に分かりやすくなります。
DI(依存性注入)を使うと、テストコードを書くときに非常に有利
例:Mockitoを使ったテスト
@ExtendWith(MockitoExtension.class)
class SomeServiceTest {
@InjectMocks
SomeService someService;
@Mock
MyUtil myUtil; // DI対象のユーティリティクラス
@Test
void testSomething() {
when(myUtil.someMethod()).thenReturn("mockedValue");
String result = someService.doSomething();
assertEquals("expected", result);
}
}
補足
もしstaticメソッドのみを使う純粋なユーティリティクラスで、DIも不要であれば、アノテーションは不要で、Spring Beanとして管理する必要もありません。
ただし、staticメソッドだけだと、テストコードで以下のことが必要です。
- Mockito.mockStatic() のような少し特殊な書き方が必要になります。
- 依存関係を差し替えるのが難しいため、テストが面倒になりがちです。
まとめ
-
DIして使う →
@Component
または@Service
-
staticメソッドだけ → アノテーション不要、DIしない
-
ユーティリティクラスが何らかの外部依存(他のBeanや設定など)を持つ、または将来的にモック化してテストしたくなる可能性があるなら、DIを使ってSpring管理Beanにするのがおすすめです。
interface(インタフェース)が必要なケース
- 実装を切り替えたい可能性がある
- ユーティリティが複雑で、契約(interface)を明確にしたい場合
- DIしてモックに差し替えやすくしたいとき
interface(インタフェース)が不要なケース
- ユーティリティが完全にstaticなメソッドだけの場合
- 実装を切り替える可能性がない単純なユーティリティ