1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Java用語、結局なんだっけ? #6】フレームワーク編 ― Spring・DI・Bean・AOP・Lombok・JPA

1
Posted at

はじめに

株式会社Good Labでエンジニアをしている コータロー です。
日々、Java・SQL・Gitなどの技術情報や、新人エンジニア向けの学習ノウハウ、
AI活用についての情報を発信しています。

Good Labについて気になった方は、コーポレートサイトもぜひご覧ください。
コーポレートサイト

「Java用語、結局なんだっけ?」シリーズの第6回です。

テーマ
#1 環境・基盤編
#2 DB接続編
#3 Web/サーバー編
#4 環境・DB・Web・例外スレッド
#5 モダンJava編
#6(本記事) フレームワーク編
#7 ビルド・運用編

今回は フレームワーク編 です。Spring / Spring Boot を中心に、新人〜2年目が「なんとなく使っているけど説明できない」用語を整理します。


この記事のゴール

  • Spring と Spring Boot の関係を説明できる
  • DI / IoC コンテナ・Bean の役割を理解できる
  • AOPが何を解決するか説明できる
  • Lombok と JPA の位置づけが分かる

① Spring Framework ― 「Javaの汎用フレームワーク」

一言で言うと

Javaアプリケーション開発を支える、機能の集合体(フレームワーク) です。
2003年から続く老舗で、現代のJavaバックエンドの デファクトスタンダード

Spring が提供する主な機能

モジュール 役割
Spring Core DI / IoC コンテナ
Spring MVC Webアプリ(Controller、View)
Spring Data DB アクセス(JPA、JDBC等)
Spring Security 認証・認可
Spring AOP 横断的関心事の処理

よくある誤解

  • 「Spring = Webフレームワーク」:違う。汎用フレームワーク で、Webは一部の機能。
  • 「Spring が重いから Java は遅い」:DIによる起動コストはあるが、実行時パフォーマンスは十分高速。

② Spring Boot ― 「Spring の設定地獄を解消したラッパー」

一言で言うと

Spring を「面倒な設定なしで」すぐ使えるようにしたフレームワーク です。
2014年リリース、現代のSpring案件はほぼ100% Spring Boot。

Spring vs Spring Boot

観点 Spring(昔) Spring Boot(今)
XML設定 何百行も必要 ほぼ不要
Tomcat 別途インストール 内蔵
依存解決 自分で組む スターターパック(spring-boot-starter-web等)
起動 WARをデプロイ java -jar app.jar で起動
設定 XML application.properties または application.yml

Spring Boot の3大特徴

  1. オートコンフィグレーション:クラスパス上の依存を見て、自動で設定を組む
  2. スターターパックspring-boot-starter-web を入れるだけでWeb開発に必要な依存が揃う
  3. 組み込みサーバー:Tomcat / Jetty / Undertow を内蔵

最小コード例

@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

@RestController
class HelloController {
    @GetMapping("/")
    public String hello() {
        return "Hello, Spring Boot!";
    }
}

これだけで Webサーバーが起動し、http://localhost:8080/ にアクセスすると "Hello, Spring Boot!" が返ります。

よくある誤解

  • 「Spring Boot は Spring を置き換えた」:違う。Spring の上に乗っかった設定不要版。中身は同じSpring。
  • 「Spring Boot は学習が簡単」:表面はシンプル。だが裏で動いている DI / AOP / Bean を理解するには時間がかかる。

③ DI(依存性注入)/ IoC コンテナ ― 「Springの心臓部」

一言で言うと

用語 一言で
DI(Dependency Injection) 必要なオブジェクトを「外から渡してもらう」設計
IoC(Inversion of Control) オブジェクト生成の主導権を「Spring に渡す」設計思想
IoCコンテナ IoCを実現する仕組み(Spring の中核)

DI なしの世界

// クラス内で new する(密結合)
public class UserService {
    private final UserRepository repository = new UserRepository();
    private final EmailNotifier notifier = new EmailNotifier();
    // ...
}

問題:

  • テスト時に UserRepository をモックに差し替えられない
  • UserRepository の生成方法が変わったら全部直す必要

DI ありの世界(Spring 流)

@Service
public class UserService {
    private final UserRepository repository;
    private final EmailNotifier notifier;

    // コンストラクタで「外から」受け取る
    public UserService(UserRepository repository, EmailNotifier notifier) {
        this.repository = repository;
        this.notifier = notifier;
    }
}

ポイント:

  • UserService依存オブジェクトを new しない
  • Spring が必要な依存を 自動で注入 してくれる
  • テスト時は モックを渡せる

Spring の DI の仕組み

1. Spring 起動時:@Component / @Service / @Repository のクラスを「Bean」として登録
2. Bean 同士の依存関係を解決
3. 必要な Bean を、必要な場所に注入(コンストラクタ・フィールド・セッター)

よくある誤解

  • 「DI = @Autowired を付けること」:違う。設計思想全体@Autowired は実現手段の1つ。
  • 「DI を使うとパフォーマンスが落ちる」:起動時のコストはあるが、実行時はほぼ影響なし。

④ Bean ― 「Springが管理するオブジェクト」

一言で言うと

Spring のIoCコンテナが管理しているJavaオブジェクト のことです。

Bean になる方法

アノテーション 用途
@Component 汎用的なBean
@Service サービス層(ビジネスロジック)
@Repository データアクセス層
@Controller Web の Controller
@RestController REST API の Controller
@Bean @Configuration クラス内で手動定義

これらのアノテーションを付けたクラスは、Spring 起動時に インスタンス化されてコンテナに登録 されます。

Bean のスコープ

スコープ 説明
singleton アプリ全体で1つ(デフォルト)
prototype DI されるたびに新規作成
request HTTPリクエストごとに1つ
session セッションごとに1つ

新規案件で singleton 以外を使うことは稀です。

よくある誤解

  • new で作ったオブジェクトもBean」:違う。Springが管理してこそBeannew で作るとDIが効かない。
  • 「Bean は1リクエスト1個」:デフォルトは singleton(アプリ全体で1個)。

⑤ AOP(アスペクト指向プログラミング) ― 「横断的関心事を分離」

一言で言うと

ログ・トランザクション・認証など「複数のメソッドに共通する処理」を、本処理から切り離して書く仕組み です。

AOP がない世界

public void doSomething() {
    log.info("メソッド開始");
    long start = System.currentTimeMillis();

    // 本処理
    repository.save(data);

    long elapsed = System.currentTimeMillis() - start;
    log.info("メソッド終了: " + elapsed + "ms");
}

「ログ出力」と「本処理」が混在しています。
これがメソッド100個あれば、ログのコードが100箇所に散らばります。

AOP がある世界

// 1. アスペクト(横断処理)を1箇所に定義
@Aspect
@Component
public class LoggingAspect {
    @Around("@annotation(Logged)")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = joinPoint.proceed();  // 本処理を実行
        long elapsed = System.currentTimeMillis() - start;
        log.info(joinPoint.getSignature() + " : " + elapsed + "ms");
        return result;
    }
}

// 2. 本処理は素直に書く
@Logged
public void doSomething() {
    repository.save(data);  // ← ログのコードがなくなった
}

AOP の典型的な用途

用途 Spring の実装
トランザクション @Transactional
キャッシュ @Cacheable
セキュリティ @PreAuthorize
非同期 @Async
ログ カスタムアノテーション

@Transactional が DI とともに AOPの裏で動いている ことを知ると、フレームワークの理解が深まります。

よくある誤解

  • 「AOPは特殊な機能」:違う。Spring 案件では @Transactional 等で日常的に使っている
  • 「AOP は性能が落ちる」:実体は プロキシオブジェクト経由の呼び出し。影響は限定的。

⑥ Lombok ― 「ボイラープレートを消すライブラリ」

一言で言うと

getter / setter / コンストラクタ / equals 等を、アノテーション1個で自動生成するライブラリ です。

旧スタイル vs Lombok

// 旧:手書き
public class User {
    private String name;
    private int age;

    public User() {}
    public User(String name, int age) { this.name = name; this.age = age; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }
    @Override public boolean equals(Object o) { /* 略 */ }
    @Override public int hashCode() { /* 略 */ }
    @Override public String toString() { /* 略 */ }
}

// Lombok版
@Data  // getter/setter/equals/hashCode/toString を自動生成
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private String name;
    private int age;
}

よく使うアノテーション

アノテーション 自動生成するもの
@Getter / @Setter getter / setter
@NoArgsConstructor 引数なしコンストラクタ
@AllArgsConstructor 全フィールドのコンストラクタ
@RequiredArgsConstructor final フィールドのコンストラクタ
@Data 上記全部入り(@Getter + @Setter + @ToString + @EqualsAndHashCode + @RequiredArgsConstructor
@Slf4j log というLoggerを自動定義

record と Lombok の使い分け

観点 record Lombok
導入 Java 16以降の標準機能 外部ライブラリ
可変性 不変(final固定) 可変も可能
継承 不可 可能
JPAエンティティ 不向き OK

新規コードで 「シンプルな不変データ」なら record「JPAエンティティや可変オブジェクト」なら Lombok が使い分けの目安です。

よくある誤解

  • 「Lombok はJavaの新機能」:違う。外部ライブラリ(アノテーションプロセッサで生成)。
  • 「Lombok の @Data は便利だから何にでも付ける」:JPAエンティティでは @EqualsAndHashCode の挙動が問題になることが多い。慎重に。

⑦ JPA / Hibernate ― 「O/Rマッパー」

一言で言うと

用語 一言で
ORM(O/Rマッパー) オブジェクト(Java)と関係DB(テーブル)の変換ライブラリの総称
JPA(Java Persistence API) Java の ORM 標準仕様
Hibernate JPA の代表的な実装

JDBC との関係と同じく、JPA は仕様、Hibernate は実装 です。

コード例

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name", nullable = false)
    private String name;

    @Column(name = "email")
    private String email;

    // getter / setter
}

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    Optional<User> findByEmail(String email);  // メソッド名から自動でSQL生成
}

// 使う側
User user = userRepository.findById(1L).orElseThrow();
List<User> all = userRepository.findAll();
userRepository.save(new User("田中", "tanaka@example.com"));

JDBC で「INSERT INTO ...」を直接書く代わりに、オブジェクトの保存・取得をメソッド呼び出しでできる のがORMの利点。

JPA のメリット・デメリット

メリット デメリット
SQLを書かずに済む 学習コストが高い
DBの種類を意識しない パフォーマンスチューニングが難しい
オブジェクトのまま扱える 思わぬN+1問題が起きやすい

JPA を使わない選択肢

  • MyBatis:SQLを直接書きつつ、結果のマッピングだけORMに任せる
  • Spring JDBC:JDBCの薄いラッパー
  • jOOQ:型安全なSQL DSL

新人〜2年目のうちは、まずJPAの基本を押さえ、その後MyBatis等にも触れると視野が広がります。

よくある誤解

  • 「JPA はDBそのもの」:違う。Java と DB の橋渡し
  • 「JPA を使えば全部速くなる」:N+1問題、遅延ロード等、ORM特有のハマりどころがある。

用語まとめ早見表

用語 一言で
Spring Framework Javaの汎用フレームワーク
Spring Boot Spring を設定なしで使える形にしたラッパー
DI / IoC 依存を「外から渡す」設計思想
IoCコンテナ DI を実現する仕組み(Springの中核)
Bean IoCコンテナが管理するオブジェクト
AOP 横断的関心事(ログ・トランザクション等)を分離
Lombok ボイラープレートを自動生成する外部ライブラリ
JPA Java の ORM 標準仕様
Hibernate JPA の代表的な実装

現場あるある誤解集

❌ 誤解 ⭕ 正しい理解
「Spring Boot は Spring の置き換え」 Spring の上に乗っかった設定不要版
@Autowired がDI」 DI は思想全体。@Autowired は実現手段
「new で作ったオブジェクトもBean」 Springが管理してこそBean
@Transactional は普通のメソッドの機能」 中身はAOPで動いている
「Lombok = Javaの新機能」 外部ライブラリ(アノテーションプロセッサ)
「JPA = Hibernate」 JPAは仕様、Hibernateは実装
「Bean のスコープは1リクエスト1個」 デフォルトは singleton(アプリ全体で1個)

演習問題

問題1:Spring と Spring Boot ⭐

次のうち、Spring Boot 固有の機能 はどれですか?

  • A. DI / IoCコンテナ
  • B. AOP
  • C. オートコンフィグレーション
  • D. @Service@Repository アノテーション
模範解答

正解:C

解説

  • C のオートコンフィグレーション は Spring Boot 固有
  • A、B、D は Spring Framework の機能(Spring Boot でも使えるが、Spring 由来)

ポイント:Spring Boot は Spring の上に「設定を自動化する仕組み」を載せたもの。基本機能はすべて Spring 由来。


問題2:DI / Bean ⭐

次のクラスは Spring の Bean として登録されますか?

public class CalculatorService {
    public int add(int a, int b) {
        return a + b;
    }
}
模範解答

正解:登録されない

解説

  • Spring の Bean になるには、@Component@Service@Repository@Controller などのアノテーションが必要
  • またはJava Config(@Bean メソッド)で明示的に登録する必要がある
  • このクラスは何のアノテーションもないので Bean にはならず、DIされない

修正例:

@Service
public class CalculatorService {
    public int add(int a, int b) {
        return a + b;
    }
}

ポイント:Spring は「アノテーションが付いたクラス」を Bean として登録する。new してもDIは効かない。


問題3:JPA と Hibernate ⭐

次のうち、正しい説明 はどれですか?

  • A. JPA は MySQL 専用の機能
  • B. Hibernate がデフォルトの JPA 実装
  • C. JPA を使うと SQL を全く書かなくなる
  • D. JPA は Spring Boot にしか組み込めない
模範解答

正解:B

解説

  • B が正解:Spring Boot の spring-boot-starter-data-jpa を入れると、デフォルトで Hibernate が使われる
  • A は誤り:JPA は DB 非依存の仕様。MySQL も PostgreSQL も Oracle も使える
  • C は誤り:複雑なクエリでは @Query で JPQL や SQL を直接書く こともある
  • D は誤り:JPA は Spring Boot に依存しない。Jakarta EE のサーバー(GlassFish等)でも使える

ポイント:JPA と Hibernate の関係は、JDBC と MySQL Connector/J の関係と同じ(仕様 vs 実装)。


まとめ

フレームワーク編の9用語のおさらいです。

  1. Spring Framework:Javaの汎用フレームワーク
  2. Spring Boot:Spring を設定なしで使える形にしたラッパー
  3. DI / IoC:依存を外から渡す設計思想
  4. IoCコンテナ:DI を実現する仕組み
  5. Bean:IoCコンテナが管理するオブジェクト
  6. AOP:横断的関心事を分離する仕組み
  7. Lombok:ボイラープレートを自動生成するライブラリ
  8. JPA:Java の ORM 標準仕様
  9. Hibernate:JPA の代表的な実装

新人〜2年目のうちに「仕様と実装の分離」「依存を外から渡す」という設計思想を掴んでおくと、Spring 案件で「なんでこう書くんだろう?」と迷う場面が激減します。


次回予告

次回(#7・最終回)は ビルド・運用編 です。

  • Maven / Gradle / プラグイン / 依存性
  • JUnit / Mockito
  • JAR / WAR / EAR の使い分け

を解説します。


参考


@kotaro_ai_lab
AI活用や開発効率化について発信しています。フォローお気軽にどうぞ!

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?