【初学者用】Spring Boot 簡易リファレンス

覚えきれる量を明らかに超えている気がするので,すぐに参照できるように自分で分かりやすい形で備忘録としてまとめます.

Spring用語

IoCコンテナ

IoCはInversion of Controlの略称とのこと.現在では,Dependency Injectionコンテナという名称の方が広く使用されている.要はDIを実施して生成されるインスタンスを管理するコンテナ.

Bean

IoCコンテナによって管理されるオブジェクト

AOP

Aspect Oriented Programming. アスペクト指向プログラミング.ログ等の予備機能やメソッド・クラスの共通処理を別クラスに抽出し,実機能の可読性を挙げるためのプログラミング.

確かにログが入り混じってると見にくいのでこれは導入したいなぁ

Advice

抽出された共通処理.@Aspectでクラスを指定し,下記のAnnotationで実行タイミングを指定する.

  • @Before
  • @After
  • @Around
  • @AfterReturning : メソッドが正常に完了した場合
  • @AfterThrowing :メソッドが例外をスローした場合
Pointcut

実行場所の指定

  • execution : メソッドが一致した場合
  • within:クラスが一致した場合
  • bean:beanが一致した場合
  • @annotation : メソッドのアノテーションが一致した場合
  • @within:クラスのアノテーションが一致した場合

なお,メソッド・クラスの指定にはワイルドカードを使用可能

  • * :任意の文字列,1階層,1引数
  • ..:任意の0文字以上の文字列,0以上階層,0以上引数
  • +:クラス,サブクラス,実装クラス

また,論理演算で重ねることも可能

Join Point

実行されているメソッド実行自体.Springではその情報の格納オブジェクト.

@Slf4j
@Aspect
public class LoggerAspect {

    @Before("execution(String com.example.demo.MyController.showList(Object))")
    public void startLog(JoinPoint jp){
        log.info("{}: Before Process", jp.getSignature());
    }
}

上記のexecutionは書くのが手間なので,以下のようにワイルドカードを用いて書くことが可能

 @Before("execution(* com.example.demo.MyController.showList(..))") 
 @Before("execution(* ...MyController..*(..))")   //ほかにも同名のが引っかかる可能性はある

Spring Boot Web

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

@SpringBootApplication

SpringBootApplicationクラスであることの指定.
@Configuration, @EnableAutoConfiguration, @ComponentScanの3つを付与しているのと同様

@Configuration

Configurationクラスであることの指定

@Bean

@Configurationクラス内でメソッドに付与することで,DIコンテナで管理することが可能.Bean名称は何もしなければメソッド名になる.

@Bean
public Object objectName(){
    return new Object();
}

//@Bean({"name"}) で別名を与えることも可能

@Componentとの使い分けは,@Componentを付与することのできないクラスをDIコンテナの管理下に置きたいときに利用するとのこと.

https://www.greptips.com/posts/1318/

@EnableAutoConfiguration

自動構成機能のEnable化

@ComponentScan

@Componentをスキャンし,DIを実施します.

@Component

Springで管理されるクラスであることを明示する.すなわち,Spring Containerに登録されるBeanでDIの対象となる.

@Controller, @Service, @Repositoryは@Componentの子

https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/beans.html#beans-stereotype-annotations

@Autowired

Springがオブジェクトを管理・依存性注入を行ってくれる.なお,Field Injection, Setter Injection, Constructor Injectionが可能だが,現在はConstructor Injectionが推奨されている.その理由としては以下のようなことが考えられるようです。

  • 単一責任の原則に反していることが判別しやすくなる
  • Spring Containerなしに使用できる(Testabilityの増加)
  • publicでないフィールドにInjectionする場合,依存性が外部に公開されない.すなわち,依存性を解決できないので,利用しにくい
  • Immutableにできる

https://www.google.com/search?q=spring+%40Autowired+field+not+recommended&oq=spring+%40Autowired+field+not+recommended&aqs=chrome..69i57j69i58j69i60l2j69i61.8680j0j7&sourceid=chrome&ie=UTF-8

また,Constructor Injectionについては,Constructorが一つの場合には@Autowiredのアノテーションは不要.

@Scope

BeanのScopeを定義することができます.指定したScopeごとにインスタンスを生成します.これは一般のServletで用いるJavaBeanと同様ですね.(そりゃそうか)

singleton, prototype, request, session, application, websocket

を選択可能.デフォルトはsingleton. request, session, applicationは@RequestScope, @SessionScope, @ApplicationScopeでも同様.

@Service

ビジネスロジックであるAnnotation.@Componentの一種.

Controlloer

@Controller

Front ControllerパターンにおけるControllerを指定する.返り値のurlにforwardする.

@Controller public class HomeController { }

@RestController

REST用のController.返り値をそのまま返す.APIとしての役割.

Request

@RequestMapping

あらゆるHttpRequestを受け付けます(GET, POST, PUT, DELETE, PATCH).また,クラスに付与することもでき,例えば@Controllerのトップレベルドメインを指定することが可能.

@RequestMapping("/")
public String doSomething(){
    return "index";
}

@GetMapping

HTTPのGETリクエストに対応します.

Attributeとして登録するためには,Modelを追加の引数として指定する

@RequestMapping("/")
public String doSomething(@RequestParam String message, Model model) {
    model.addAttribute("message", message);
    return "index";
  //return "redirect:/index";  // redirectの場合
}

@RequestParam

@RequestParamでリクエストパラメータの取得が可能.引数名と同一であれば省略可能であり,異なるのであれば,@RequestParam(“name”)としてパラメータ名を指定する.

なお,RequestParamに対応したパラメータがない場合はデフォルトではエラーとなるため,@RequestParam(required=false)を指定するとパラメータがなくとも応答可能となる.

@ModelAttribute

引数パラメータを自動的にAttributeに追加する.下記で自動的に追加される.@RequestParamと異なり,@ModelAttributeはパラメータがなくともよい.

 @RequestMapping("/")
public String doSomething(@ModelAttribute String message) {
    return "index";
} 

@PostMapping

HTTPのPOSTリクエストに対応します.

@PathVariable

指定したpathの一部分をそのまま取得することが可能.下記の例では,{id}部分が引数idに格納される.

@GetMapping("/edit/{id}")
public String doSomething(@PathVariable Long id, Model model){
    model.addAttribute("obj", repository.findById(id));
    return "index";
}

Format

@NumberFormat(pattern = “#,###”)

指定したパターン文字列を数値に変換します

@DateTimeFormat

文字列をLocalDateオブジェクトに変換します.文字列で指定する方法と規定されたパターンから選択する方法がある

@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
@DateTimeFormat(pattern = "yyyy-MM-dd")

Class, Interface

ApplicationContext

IoCコンテナのinterface.

 (Hoge) appContext.getBean("hoge"); //BeanをStringから取得.名前は先頭小文字のクラス名
appContext.getBeanDefinitionNames(); //登録された全てのBean名称を取得

CommandLineRunner

コンポーネントスキャン時にコマンドラインとして実行される.コンポーネントスキャンは@ComponentScanが付与されたクラスが起動されたときに実施される.そのため,基本的には起動時である.

error.html

作製しておけば,エラー時に自動的に呼び出してくれる.statusにはステータスコード,errorにはエラーメッセージが格納されており,そのまま利用することが可能.

“error”というフォルダを作製すれば,その中でステータスコードごとにhtmlファイルを分割することも可能.

schema.sql, data.sql

resources/schema.sql, data.sqlは作成した場合に自動で読み込まれ,テーブルの作成等を起動時に行うことが可能.

なお,この場合はspring.jpa.hibernate.ddl-auto=noneを設定しておかないと競合が発生する

UserDetailsService

ユーザー認証時に使用される.

Spring Validation

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

https://docs.jboss.org/hibernate/validator/6.1/reference/en-US/html\_single/#validator-defineconstraints-spec

@Validated

Validationを掛けたいパラメータに指定する.BindingResultがValidation結果を保持しています.

@RequestMapping("/")
public String doSomething(@Validated @ModelAttribute DataObject object, BindingResult result) {
    return "index";
}
@Data
class DataObject{
    @NotBlank
    @Size(max = 30)
    private String name;

    @NotNull
    @Pattern(regexp = "[0-9]*?")
    private String id;
}

だいたい確認したいValidationはそろっているので,公式サイトから確認すること

@NotBlank, @NotEmpty, @NotNull

@Min, @Max

@Size, @Pattern

自作Validatorを作製する時

ConstraintValidator

これを継承したクラスを作製する.必須Override項目はisValidのみ.

また,以下のアノテーションを実装した自作アノテーションを作製することで,自作Validatorによるアノテーションチェックを可能とする

@Target

アノテーションの適用箇所を規定する.ElementType.METHOD, ElementType.FIELD等がある

@Retention

アノテーションの保持期間を指定する.RetentionPolicy.RUNTIME, RetentionPolicy.CLASS等がある

@Constraint

アノテーションのチェック実行対象を指定する.自作クラスを指定する.メソッド類はよくわからないが必須らしい.また調べる.

@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.CLASS)
@Constraint(validatedBy = MyValidator.class)
public @interface MyValidation {
    String message() default "invalid";
    Class<?>[] groups() default{};
    Class<? extends Payload>[] payload() default {};
}

application.properties

spring.messages.fallback-to-system-locale

デフォルトはtrueで,サーバー言語を設定します.(通常の設定であれば日本語のはず)

falseにすることで,defaultのmessages.propertiesが読み込まれる.

spring.messages.basename

読み込むファイル名の指定が可能.resourcesをルートとした相対パスで指定する.

spring.datasource.url

jdbcを指定する.なお,jdbcの設定としてmemが存在し,memの場合はApplication終了と同時にデータベースは破棄される.(In memoryなので当然か)

spring.h2.console.enabled

Spring BootでDevToolsをEnableにしていない場合は,こちらで設定することでh2Consoleが起動される.

spring.datasource.url=jdbc:h2:mem:testdb
spring.h2.console.enabled=true

spring.jpa.hibernate.ddl-auto=create, create-drop, update,none

  • create : @Entityのテーブルがあれば削除し,再生成を行う.

  • create-drop : createに加えてSpring Boot終了時にテーブルを削除する.これはmemの場合はcreateと同様.

  • update : @Entityのテーブルがない場合に作成する.

  • none:何もしない

spring.jpa.show-sql=true

HibernateによるDatabaseのSQL操作がConsoleに出力されるようになります.Intellijの場合,以下のようにconsoleに出力されるようになる

Spring Data JPA

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

JPAとは

JPAとはJava Persistence APIの略称で,ORMです.Object Relation Mapping.自分の認識では,JDBCがqueryベースでデータベーステーブルを直接操作するのに対して,JPAはJavaオブジェクトがレコード・テーブルに対応して,Javaオブジェクトベースでデータベース操作ができるという違いがある.

JPAの方がJDBCに対して,クラスがデータベース内の依存関係を表現しやすく,オブジェクト指向に向いているということです.

@Entity

エンティティであるクラス.カラムに対応するということ

@Id

フィールドをエンティティの主キーに設定する

@GeneratedValue

@IDアノテーションとの併用.フィールドとして主キーを自動生成する.

GenerationTypeとして,AUTO, IDENTITY, SEQUENCE, TABLEを利用可能.DefaultはAUTOで使用するRDBMSに応じて最適なものが選択される.

@GeneratedValue(strategy = GenerationType.IDENTITY)

以下が詳しい

https://qiita.com/KevinFQ/items/a6d92ec7b32911e50ffe

@Repository

データベースレポジトリであることを示します.JpaRepositoryを継承する場合にはなくてもよい.

@ManyToOne

多対一のテーブルを指定する.

@ManyToOneのみの短方向でもデータベースとして機能するが,双方向で関連させたほうが良いらしい.検索しやすいため.

@OneToMany

一対多のテーブルを指定する.mappedByで多の方のcolumn名を指定します.

@OneToMany(mappedBy = "column_name")

@Query

SQLやJPQLを直接発行する関数を作製可能. JPQLはEntityに対する操作で,SQLはデータベースに対して直接発行します.

@Query("SELECT o FROM Obj o WHERE o.name LIKE ?1")  //JPQL. 引数は ?1 ?2 等でアクセス
Collection<Obj> searchByName(String name)

@Query("SELECT * FROM obj_table WHERE name LIKE :name, nativeQuery=true) //SQL形式
Collection<Obj> searchByName(String name)

Class, Interface

JpaRepository

@Repositoryとしての最低限の機能が提供されている.

関数を定義するだけで,自動的に対応したクエリを作製してくれる.基本的には,以下のように定義可能.その他にもcount, exists, delete, LessThan, GreaterThanなども作成可能.

repository.findByXxxx //フィールド名検索
repository.findByXxxLike

Spring Security

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<html xmlns:sec="http://www.thymeleaf.org/extras/spring-security">

@EnableWebSecurity

Spring Securityの機能を有効にするクラスを指定する

Classes and Interface

WebSecurityConfigurerAdapter

@Configuration, @EnableWebSecurityアノテーションを付与して,SecurityのConfigurationを設定する.

設定可能なのは,configure(http) リクエスト用とconfigure(auth)認証用とconfigure(web)のweb全体に関する設定の3つ.

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
  //HttpRequestに対するセキュリティ
http.authorizeRequests()
            .antMatchers("/login", "/error").permitAll()     //login, errorには認証なしで
            .anyRequest().authenticated()           //その他は認証あり
            .and()
        .formLogin()                                         //ログインフォーム
            .loginPage("/login")                //ログインフォームページ指定
            .defaultSuccessUrl("/")              //ログインが成功した時のリダイレクト先
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  //認証方法の設定
auth.inMemoryAuthentication()      //メモリ内認証 auth.userDetailsService()でDB
        .withUser("admin")
        .password("password")
        .authorities("ROLE_ADMIN")
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
    //Web全体のセキュリティ
       web.ignoring().antMatchers("/css/**", "/img/**", "/webjars/**"); //静的リソースをセキュリティから除外します.認証なしでロゴ等が表示されるようにするため.

    }
}

https://docs.spring.io/spring-security/site/docs/current/reference/html5/#logout-java-configuration

https://docs.spring.io/spring-security/site/docs/4.1.4.RELEASE/reference/html/jc.html

PasswordEncorder

PasswordEncorderの共通Interface.以下のような実態クラスが使用可能.

  • BCryptPasswordEncoder
  • Argon2PasswordEncoder
  • Pbkdf2PasswordEncoder

使用方法はencodeしてmatchesさせるだけ.

BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String result = encoder.encode("myPassword");
encoder.matches("myPassword", result); 

勿論だが,Client⇔Server間の通信を暗号化している訳ではない.ここはHTTPSプロトコルの担当であるので,HTTPで通信している人は注意.

認証情報の取得

以下のようにしてControllerから認証情報を取得することが可能

@GetMapping("/")
public Object doSomething(Authentication auth, Model model){}
public Object doSomething(Principal auth, Model model){} 
public Object doSomething(Model model){
    Authentication auth = SecurityContextHolder.getContext().getAuthentication;
}  

logout.html

自動で生成されている.ここにアクセスすることでログアウトすることが可能.

application.properties

spring.messages.basename=org/springframework/security/messages

一部のエラーメッセージを日本語化可能.

Thymeleaf 記法

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

springboot thymeleaf

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
 <html xmlns:th="http://www.thymeleaf.org"> 

th:object

フォームにバインドするオブジェクトを指定する.該当オブジェクトには上記の選択変数式でアクセス可能となる.

th:field

id, name, valueに同一の値を設定する

th:errorclass=”hoge”

th:fieldがValidationでErrorとなった時にclass名に”hoge”を動的に追加する.すなわち,th:fieldがErrorの時にclass=”original hoge”となる

<input type="text" class="form-control" th:errorclass="is-invalid" th:field="*{name}">

この場合,nameがvalidationの結果Errorになった場合,class=”form-control is-invalid”となる.

https://www.thymeleaf.org/doc/tutorials/3.0/thymeleafspring.html#simplifying-error-based-css-styling-therrorclass

th:errors

指定したフィールドのValidation Errorを全て取得する

th:href

外部リソースを参照する場合に使用します.動的にリンクを作製することも可能で,以下のような規則に基づいて作成されます.

//obj.id=5のとき
th:href="@{/obj/contents(contentsId=${obj.id})} // ⇒/obj/contents?contentsId=5
th:href="@{/obj/contents/{contentsId}(contentsId=${obj.id})} // ⇒/obj/contents/5

https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#link-urls

hoge.cssをスタイルシートに設定する

hoge.jsを埋め込む.Bootstrapの場合は,body最下部へ配置すること.

th:each

Collectionの繰り返しを実装できる

<div th:each="object : ${list}">
    <div>[[${object.id}]] - [[${object.content}]]</div>
</div>

th:if

タグに追加することで,条件式が満たされる場合に該当タグが実行されます.タグはなんでもよい.

<div th:if="${list.size() == 0}">
    該当データがありません
</div>

th:replace

特定タグに置き換えます.指定にはフラグメント式を利用します.下記の例では,fragments/header.html内のheaderというfragmentに置換されます.

<div th:replace="~{fragments/header :: header}"></div>

https://www.thymeleaf.org/doc/articles/layouts.html

th:include

これは非推奨となりました.th:replaceかth:insertを利用します

th:remove

タグ内から,指定した条件に応じてタグを削除します.replaceやinsertと併用することが多い様子.

指定できるものは,all, body, tag, all-but-first, noneがあります.

https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#removing-template-fragments

th:block

HTMLとして出力しないタグで,Thymeleafの処理に使用可能.

th:for

<input type="radio" th:field="*{obj}">
<label th:for="${#ids.prev('obj')}">xxxx</label>

thymeleaf layout dialect

レイアウト用のライブラリ

<dependency>
    <groupId>nz.net.ultraq.thymeleaf</groupId>
    <artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>
<html xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout">

layout:fragment

layoutのfragmentを選択できます.後に別ファイルからth:replace, th:insertで利用することができます.

<div layout:fragment="content">
</div>

layout:decorate

レイアウトを指定できます.下記ではlayout.htmlを指定したことになります.

layout:decorate="~{layout}"

spring-security

<html xmlns:sec="http://www.thymeleaf.org/extras/spring-security">

sec:authorize

th:ifと意味的には同じ.以下のようにして.特定のRoleを持っているときに表示させるなどが可能

 <div sec:authorize="hasRole('ROLE_ADMIN')">xxxx</div>

https://github.com/thymeleaf/thymeleaf-extras-springsecurity#namespace

その他表記

#{}

外部ファイル参照.標準のSpringBootファイル構成においては,resources下のpropertiesファイルに記載されたproperty.

${}

変数式.Attribute呼び出し

${@…}

DIコンテナが管理しているBeanを参照

*{}

選択変数式と呼ぶらしい.Attribute呼び出しの短縮記法.formにバインドされたObjectに短縮系でアクセス可能.なお,${object.id}としても同様にアクセスできる.

<form th:action="@{/}" th:object="${object}" method="post">
    <label for="id">ID:</label>
    <input type="text" th:field="*{id}">
</form>

@{}

リンク先を指定する.

[[hogehoge]]

インライン表記

~{}

フラグメント式.フラグメントを指定する際に使用する

${T(package.class).STATICFIELD

Staticフィールドを参照可能

#ids

以下の形式で,idを呼び出すことができ,繰り返し処理等で役に立ちそうなユーティリティメソッド

${#ids.seq('someId')}
${#ids.next('someId')}
${#ids.prev('someId')}

https://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html

HTML

HTML一般なことはこちらに記載

<

div class=”hoge”>

グループIDという認識.CSSで一括して操作を行うことが可能な単位.前後に改行が入る

グルーピングタグ.はインライン要素として使用可能なグルーピングタグ.divは前後に改行が入る点が異なる

<

script>

javascript等のスクリプトを文書内に埋め込む.

<

nav>

主要なナビゲーションセクションであることを示す.すなわち,他ページへのリンクを掲載するセクションであることを示す.セクションタグの一種.

<

ul>

unordered list.箇条書きで示す場合に利用される

<

ol>

ordered list

  • <

    ul>等のlistとセットで使用され,一つ一つの項目を表すタグ.

    イタリック体表記となる.


    horizontal rule.水平の横線を描画する.

    と併用する.のidと