【Spring】アノテーション

カッコはアノテーションを記述する場所

@Component(クラス)

SpringDIコンテナにbeanとして登録したいクラスへ付与する。
コンポーネントスキャンの対象になっている必要あり
DIとして使用する場合、シングルトンになるため、メンバ変数を使用している場合は共有されることを注意。(回避方法あり)

@Component
public class OfferComponent {
    ...
}

コンポーネントスキャン対象の設定方法】
spring-mvc.xml(servlet-context.xml)に下記を記載する
※設定方法は他にも方法あり

</beans><context:component-scan base-package="jp.co.demo" /></beans>

@Controller(クラス)

@Componentと基本的には同じ働きをするが、SpringMVCでControllerの役割となるクラスに付与する。

@Controller
public class OfferController {
    ...
}

@Service(クラス)

@Componentと基本的には同じ働きをするが、Service層(ビジネスロジック等)を対象としている。

@Service
public class OfferService {
    ...
}

@Repository(クラス)

@Componentと基本的には同じ働きをするが、Persistence層(DAO等のDBアクセスを行うクラス)を対象としている。

@Repository
public class OfferRepository {
    ...
}

@RestController(クラス)

REST API 用の Controller クラス(Viewに遷移せず、メソッドの戻り値をそのままレスポンスとして返す)に使用する。

@RestController
public class RestController {
    ...
}

@RequestMapping(クラス、メソッド)

URLリクエストとクラス、メソッドのマッピングを行う。

【属性】

@RequestMapping(value="/test", method=RequestMethod.GET, headers="Accept=application/*", params="id=002")

// 省略してvalueのみ指定可能(POSTになる)
@RequestMapping("/test")
value コンテキストルートからのパスを記載する。複数指定可能。ワイルドカード使用可能。
method GET、POST等を指定する。複数指定可能。省略時はPOSTになる。
headers HTTPヘッダ名のみ指定されている場合は、そのヘッダが存在するかどうかでマッチの判定。ヘッダ名と値が指定されている場合は、ヘッダにその値が設定されているかどうかでマッチの判定。
params リクエストパラメーターを指定する。

【使用例】

@Controller
// コンテキストルート/offerでこのクラスを指定
@RequestMapping("/offer")
public class OfferController {

    // コンテキストルート/offer/offer_initDisplayでこのメソッドを指定
    @RequestMapping("/offer_initDisplay")
    public String initDisplay(Model model) {
        return "offer";
    }

    // URLを複数指定可能、ワイルドカード使用可能
    // ?は1文字、*は0文字以上(/offer2/aとか不可)、**は0文字以上(/offer3/aとか可能)
    @RequestMapping(value = {"/offer1?","/offer2*", "/offer3/**"})
    public String initDisplay2(Model model) {
        return "offer";
    }

    // methodは複数指定可能
    @RequestMapping(value="/offer4", method={RequestMethod.GET, RequestMethod.POST})
    public String initDisplay3(Model model) {
        return "offerConfirm";
    }

    // paramsでリクエストの値を指定可能
    @RequestMapping(value="offer_confirm", params="userId=1")
    public String confirm(Model model) {
        return "offerConfirm";
    }

    // paramsは複数指定可能
    @RequestMapping(value="offer_confirm", params={"userId=1", "name=あ"})
    public String confirm2(Model model) {
        return "offerConfirm";
    }
}

@PostMapping/@GetMapping(メソッド)

※Spring 4.3以降
RequestMappingとほぼ同様。メソッドが省略できる。
methodがPOSTの場合:PostMapping
methodがGETの場合:GetMapping

@Controller
@RequestMapping("/offer")
public class OfferController {

    @PostMapping("/offer_initDisplay")
    public String initDisplay(Model model) {
        return "offer";
    }

    @GetMapping(value = {"/offer1?","/offer2*", "/offer3/**"})
    public String initDisplay2(Model model) {
        return "offer";
    }
}

@ModelAttribute(メソッドの引数、メソッド)

メソッドの引数:画面(jsp)からフォームの値を受け取り、Modelに格納する。画面(jsp)のModelAttributeと紐づける必要あり。
メソッド:RequestMappingの前に実行される。Modelに格納する。

【メソッドの引数】
@ModelAttribute("{受け取るformの名前}") {格納する型} {格納する変数名}

@Controller
public class ConfirmOffer {

    @PostMapping("offer_confirm")
    public String confirm(Model model,
            @ModelAttribute("offerForm") OfferForm form) {

        // 変更すると変更した値が画面に渡される
        form.setName("値を変更");

        // Modelに格納済みのため、model.addAttribute不要で画面で使用可能
//        model.addAttribute("offerForm", form);
        return "offer/confirmOffer";
    }
}

画面(jsp)
modelAttributeでControllerの@ModelAttributeの値と紐づける必要あり

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<form:form modelAttribute="offerForm">
    <label>ユーザーID:</label>
    <form:input path="userId"/><br>
    <label>名前:</label>
    <form:input path="name"/><br>
    <input type="submit" value="確認へ進む" formaction="offer_confirm"/>
</form:form>
</body>
</html>

【メソッド】
@ModelAttribute("{modelに格納する変数名}")

@Controller
public class ConfirmOffer {

    // RequestMappingの前に実行される。値をModelにセットする。メソッド名は不問
    @ModelAttribute("aiueo")
    private String setupForm() {
        return "あいうえお";
    }

    @RequestMapping("offer_confirm")
    public String confirm(Model model) {

        // Modelの変数を使用
        System.out.println(model.getAttribute("aiueo"));
        return "offer/confirmOffer";
    }
}

@PathVariable(メソッドの引数)

URLに含まれる動的なパラメータを受け取る。
【属性】

@PathVariable(name="id", required=true) String userId

// 省略時
@PathVariable("id") String userId
name URLに含まれるパラメータに紐づく
required true:必須、false:必須でない。省略時はtrue:必須

使用例

@Controller
public class OfferController {

    @GetMapping("/offer_initDisplay/sample_{id}")
    public String initDisplay(Model model,
            @PathVariable("id") String userId) {

        // 使用
        System.out.println(userId);

        return "offer/offer";
    }
}

@RequestParam(メソッドの引数)

GETやPOSTのパラメータの値を受け取る。
【属性】

@RequestParam(name="id", required = true, defaultValue="default") String userId)

// 省略時
@RequestParam("id") String userId
name URLに含まれるパラメータに紐づく
required true:必須、false:必須でない。省略時はtrue:必須。defaultValueがある場合はtrueでもエラーにならない
defaultValue リクエストパラメータが指定されなかった時のデフォルト値を指定

【使用例】
・GETの場合
URLのパラメータを取得する
http://localhost:8080/demo/offer_initDisplay?id=sample

@Controller
public class OfferController {

    @GetMapping("/offer_initDisplay")
    public String initDisplay(Model model,
            @RequestParam(name="id") String userId) {

        System.out.println(userId);

        return "offer/offer";
    }
}

・POSTの場合
formで送信された値を取得する

@Controller
public class ConfirmOffer {

    @PostMapping("offer_confirm")
    public String confirm(Model model,
            @RequestParam(name="userId") String id,
            @RequestParam(name="name") String name,
            String userId) { // @RequestParamなしでも取得可能

        System.out.println(id);
        System.out.println(name);

        return "offer/confirmOffer";
    }
}

jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<form method="post">
    <label>ユーザーID:</label>
    <input type="text" name="userId"/><br>
    <label>名前:</label>
    <input type="text" name="name"/><br>
    <input type="submit" value="確認へ進む" formaction="offer_confirm"/>
</form>
</body>
</html>

@Scope(クラス)

インスタンスのスコープ(ライフサイクル)を変更する。
コントローラーやサービスはシングルトン(インスタンスを使いまわす)のため、メンバ変数の共有を防ぐためにrequestやprototypeを指定する。

singleton コンテナに対してインスタンスを1つだけ作成(デフォルト)
prototype 呼び出される毎にインスタンスを作成
request 1回のHTTPリクエスト毎にインスタンスを作成
session HTTPセッション毎にインスタンスを作成
@Controller
@Scope("request")
public class OfferController {
    // メンバ変数
    String sampleName;

    @GetMapping("/offer_initDisplay")
    public String initDisplay(Model model){
        System.out.println(sampleName);    // リクエスト毎にインスタンスが作成されるためnullが表示(共有されない)
        // メンバ変数に代入
        serviceName = "a";
        return "offer";
    }
}

@Autowired(クラス)

DIコンテナからBeanをDIする。(型が一致するクラスをDIする)
newを使ったインスタンス化と同じ。
シングルトンのためメンバ変数を使用している場合は、値が共有されるため注意する。(回避方法あり)

【属性】

@Autowired(required=false)
required true:対象のBeanがDIコンテナにないとエラー、false:DIコンテナになくてもエラーにならない。省略時はtrue。

【使用方法】
【Spring】DI - アルパカノフンに記載

@Qualifier(クラス)

@Autowiredと併用する。
@Autowiredでbean名を指定したい場合に使用する。

@Autowired
@Qualifier("beanName")

@Inject(クラス)

@Autowiredと同じ機能。
javaアノテーション

@Resource(クラス)

DIコンテナからBeanをDIする。(名称が一致するクラスをDIする)
javaアノテーション

@Resource(name="beanName")
name bean名を指定する。省略時はフィールド名の名前から指定する。

@Value(フィールド)

主にプロパティファイルの値を入力する際に使用。
【Spring】テクニック - アルパカノフンに記載。

@Transactional(クラス、メソッド)

トランザクションを行う。
【Spring】MyBatis - アルパカノフンに記載。