Spring Coreとは?
Spring CoreはSpring Frameworkの中核機能を提供するモジュールで、DI(依存性注入)コンテナとBean管理機能を中心に構成されています。アノテーションベースの設定により、疎結合で保守性の高いアプリケーション開発を実現します。
Bean定義 - @Component系
汎用コンポーネント
@Component
public class MyComponent {
// DIコンテナに登録される
}
ビジネスロジック層
@Service
public class UserService {
// サービス層のビジネスロジック
}
データアクセス層
@Repository
public class UserRepository {
// DB例外変換が自動適用される
}
プレゼンテーション層
@Controller
public class UserController {
// リクエストハンドラ
}
依存性注入(DI)
コンストラクタ注入(推奨)
@Service
public class UserService {
private final UserRepository repository;
// @Autowired省略可(単一コンストラクタ)
public UserService(UserRepository repository) {
this.repository = repository;
}
}
不変性保証、テスト容易、循環依存検知
フィールド注入(非推奨)
@Service
public class UserService {
@Autowired
private UserRepository repository;
// テストが困難、循環依存検知不可
}
Setter注入(オプション依存時)
@Service
public class UserService {
private CacheService cache;
@Autowired(required = false)
public void setCache(CacheService cache) {
this.cache = cache;
}
}
Bean Scope
singleton(デフォルト)
@Scope("singleton")
アプリ全体で1つのインスタンス
prototype
@Scope("prototype")
DI時に毎回新規作成
request
@RequestScope
HTTPリクエスト毎
session
@SessionScope
HTTPセッション毎
@Component
@Scope("prototype")
public class PrototypeBean {
// 毎回新しいインスタンスが生成される
}
@Configuration & @Bean
Javaベース設定
@Configuration
public class AppConfig {
@Bean
public DataSource dataSource() {
return new HikariDataSource();
}
@Bean
public JdbcTemplate jdbcTemplate(DataSource ds) {
return new JdbcTemplate(ds);
}
}
● サードパーティライブラリのBean化
● 複雑な初期化ロジック
● 条件付きBean生成(@Conditional)
Beanライフサイクルコールバック
初期化時
@PostConstruct
public void init() {
// DI完了後に実行
logger.info("初期化");
}
破棄前
@PreDestroy
public void cleanup() {
// Bean破棄前に実行
pool.shutdown();
}
インターフェース方式
public class MyBean
implements InitializingBean {
@Override
public void afterPropertiesSet() {
// 初期化処理
}
}
よく使うパターン
@Qualifier - Bean選択
@Service
public class UserService {
private final DataSource dataSource;
public UserService(
@Qualifier("mainDB") DataSource ds) {
this.dataSource = ds;
}
}
同一型のBeanが複数ある場合に使用
@Primary - デフォルト指定
@Configuration
public class DataSourceConfig {
@Bean
@Primary // デフォルトとして使用
public DataSource mainDB() {
return new HikariDataSource();
}
@Bean
public DataSource subDB() {
return new HikariDataSource();
}
}
@Value - プロパティ注入
@Component
public class AppConfig {
@Value("${app.name}")
private String appName;
@Value("${db.timeout:30}")
private int timeout; // デフォルト値30
}
@Lazy - 遅延初期化
@Component
@Lazy // 初回使用時に初期化
public class HeavyComponent {
public HeavyComponent() {
// 重い初期化処理
}
}
@ComponentScan
@Configuration
@ComponentScan(
basePackages = {"com.example.service", "com.example.repository"},
excludeFilters = @ComponentScan.Filter(
type = FilterType.ANNOTATION,
classes = ExcludeFromScan.class
)
)
public class AppConfig {
// 指定パッケージ配下の@Component系を自動検出
}
basePackages
スキャン対象パッケージを指定
excludeFilters
特定のクラスを除外
includeFilters
追加で含めるクラス
lazyInit
遅延初期化を一括指定
実務で役立つTips
コンストラクタDI優先
不変性を保証し、テストが容易。フィールドインジェクションは避ける。
循環依存に注意
A→B→Aのような相互依存は設計の見直しが必要。@Lazyで回避も可能。
適切なスコープ選択
デフォルトのsingletonで十分なケースがほとんど。prototypeは慎重に。
Bean名の競合回避
@Component("beanName")で明示的に名前を指定。@Primaryや@Qualifierを活用。
Beanライフサイクル処理フロー
コンテナ起動時にBeanが生成され、停止時に破棄される(singletonスコープ)