spring boot学習ノート

15008 ワード

[TOC]
spring boot
  • 特徴:
  • 1、複雑化を簡略化し、構成を簡略化する
  • .
  • 、注目されているのは次世代フレーム
  • です.
  • 、マイクロサービスの入門レベルのマイクロフレーム
  • Request Mappingは複数の経路を使って同じ方法にアクセスできるなら、value={"/hello 1]、'/hello 2'でいいです.
    Spring-Data-Jpa:JPAは一連のオブジェクトの持続化の基準を定義しています.現在この規格を実現している製品はhibernate、Toplinkなどがあります.
    NOTE:1、前置知識:mavenを利用してプロジェクトを構築し、Spring注釈、RESTful API 2.Spring MVC 3.Java、Mavenなどのバージョンを勉強する必要はない.
    Sprigbootの作成
    ideaでSpring Initializrで作成します.
    プロジェクトの設定
    方法1:appication.propertiesに追加する
    
    server.port=8081
    server.context-path=/girl
    
    方法二:appication.ymlファイルの追加を作成します.
    server:
      context-path: /girl
      port: 8082
    
    設定ファイルの属性を変数にどうやって注入しますか?
    方法の1:Valueを使って注釈をつけます.
    プロファイル:appication.yml
    server:
      port: 8080
    cupSize: B
    
    NOTE:ここのcupSize属性はserverと並んでいます.そうでないとエラーが発生します.
    javaファイル:Hello Controller.java
      @Value("${cupSize}")
        private String cupSize;
    
        @RequestMapping(value = "/hello",method = RequestMethod.GET)
        public String say(){
            return cupSize;
        }
    
    @value:プロファイルの属性値を属性に注入する
    方法二:クラスオブジェクトの使用
    プロファイル:appivation.yml
    girl:
      cupSize: B
      age: 18
    
    対象クラス:Girl Properties
    @Component
    @ConfigurationProperties(prefix = "girl")
    public class GirlProperties {
        private  String cupSize;
        private  Integer age;
    
        public void setCupSize(String cupSize) {
            this.cupSize = cupSize;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public String getCupSize() {
            return cupSize;
        }
    
        public Integer getAge() {
            return age;
        }
      }
    
    NOTE:@ConfigrationProperties(prefix="girl"):接頭辞を取得するのはgirlの構成@Componentです.配置ファイルの情報と一致して、一般的なpojoをspring容器に実例化するという意味です.
    controler:
    @RestController
    public class HelloController {
    @Autowired
     private GirlProperties girlProperties;
    
        @RequestMapping(value = "/hello",method = RequestMethod.GET)
        public String say(){
            return girlProperties.getCupSize();
        }
    }
    
    マルチ環境設定
    環境一:appication-dev.yml
    server:
      port: 8080
    girl:
      cupSize: B
      age: 18
    
    環境二:appication-prod.yml
    server:
      port: 8080
    girl:
      cupSize: F
      age: 18
    
    appication.ymlに配置する
    Spring:
        profiles:
            active:dev
    
    activeによって異なる環境を使うことができます.
    Controllerの使用
    @Controller:http要求を処理します@Request Controller:Spring 4の後で新たにプラスする注釈、もとはjsonに戻ります@ReponseBody協力@Controller@Request Mapping:配置urlマッピングが必要です.
    urlのパラメータはどう処理しますか?
    @PathVarableはurl内のデータを取得する(要求中は、retsfulタイプ要求:/hello/${id}@RequestParamは要求パラメータの値を取得する(正常要求:/hello?id=23)@GetMappingコンビネーションコメント(@GetMapping=value/say)は@RequestMapping=RequestMappingに相当する.
    データベース操作
    Spring-Data-Jpa JPA(Java Persistence API):一連のオブジェクトの持続化の基準を定義しています.現在この規格を実現している製品は、Hibernate、TopLinkなどがあります.
    テーブルを作成
    pom.xmlファイルの導入依存度:
            
                org.springframework.boot
                spring-boot-starter-data-jpa
            
            
                mysql
                mysql-connector-java
                5.1.24
            
    
    Note:mysql     ,       
    
    appication.ymlファイルの設定データソースとjpa
      datasource:
            driver-class-name: com.mysql.jdbc.Driver
            url: jdbc:mysql://localhost:3306/dbgirl
            username: root
            password:
      jpa:
          hibernate:
               ddl-auto: create
          show-sql: true
    
    Note:datasource:     
    ddl-auto:
    creat                    
    update:         ,                
    create-drop:              
    none:     
    validate:           ,          
    show-sql:  sql  
    
    ガールズ実体類:
    @Entity
    public class Girl {
        @Id
        @GeneratedValue
        private Integer id;
    
        private String cupSize;
    
        private  Integer age;
        //   get set       
    }
    
    Note:@Entity:jpa特性は、エンティティ類がデータベースに対応するテーブル@Idを表します.マスタキー@Generate edValue:自動生成
    APIインターフェース開発
    要求のタイプのパス機能GET/girlsは、女の子リストのPOST/girlsを取得して、女の子GET/girls/idを作成しました.idで女の子のPUT/girls/idを調べて、idで女の子のDELETE/girls/idを更新しました.
    インターフェースを作成してJpaを継承します.
    public interface GirlRepository extends JpaRepository{
    
        //       
        public List findByAge(Integer age);
    }
    
    controllerを作成します
    @RestController
    public class GirlController{
    
        @Autowired
        private GirlRepository girlRepository;
    
        /*
                 
         */
        @GetMapping(value = "/girls")
        public List girlList(){
    
            List girlList = girlRepository.findAll();
    
            return  girlList;
        }
        /*
              
         */
        @PostMapping(value = "/girls")
        public Girl girlAdd(@RequestParam("cupSize") String cupSize,@RequestParam("age") Integer age){
            Girl girl = new Girl();
            girl.setAge(age);
            girl.setCupSize(cupSize);
            return girlRepository.save(girl);
        }
    
        /**
         *       
         * @param id
         * @return
         */
        @GetMapping(value = "/girls/{id}")
        public Girl girlFindOne(@PathVariable("id") Integer id){
            return girlRepository.findOne(id);
        }
    
        /**
         *       
         * @param id
         * @param cupSize
         * @param age
         * @return
         */
        @PutMapping("/girls/{id}")
        public Girl girlUpdate(@PathVariable("id") Integer id, @RequestParam("cupSize") String cupSize
                , @RequestParam("age") Integer age){
            Girl girl = new Girl();
            girl.setId(id);
            girl.setCupSize(cupSize);
            girl.setAge(age);
            return girlRepository.save(girl);
        }
    
        /**
         *       
         * @param id
         */
        @DeleteMapping(value = "/girls/{id}")
        public void girlDelete(@PathVariable("id") Integer id){
            girlRepository.delete(id);
        }
    
        //          
        @GetMapping("/girls/age/{age}")
        public ListgirlListByAge(@PathVariable("age") Integer age){
            return girlRepository.findByAge(age);
        }
    
    }
    
    ノート:注入時にideaのspring注解に注意して、warningかどうか管理します.
    saveはidがあるときに更新します.メインキーがないときは追加します.
    事務管理
      @Transactional
        public void  insertTwo(){
            Girl girlA = new Girl();
            girlA.setCupSize("B");
            girlA.setAge(18);
            girlRepository.save(girlA);
    
            Girl girlB = new Girl();
            girlB.setCupSize("Cccc");
            girlB.setAge(19);
            girlRepository.save(girlB);
        }
    
    方法の上にtranslationの注釈を追加して、事務管理を開始すると表しています.
    spring boot進級のweb進級
    フォームの検証
    Controllerメソッドでは対象を使ってフロントデータを受信し、対象の対応するクラスで検証が必要な属性に@Minコメントを追加します.
    @Min(value = 18, message = "      ")
    private Integer age;
    
    ここでvalueは年齢最小値が18で、18未満の検証が通らないことを表しています.メッセージは認証が通らない時に提示された情報です.
    Controllerメソッドでは、イメージの前面に@Validコメントを追加し、BindingResultを使ってメッセージを受信します.
    @PostMapping("/boys")
    public Boy addBoy(@Valid Boy boy, BindingResult bindingResult) {
        //        ,       
        if (bindingResult.hasErrors()) {
            //           
            System.out.println(bindingResult.getFieldError().getDefaultMessage());
            //   null   
            return null;
        }
        return boyRepository.save(boy);
    }
    
    AOPを使って要求を処理します.
    概念
    AOP(面に向かってプログラミングする)はプログラミングの範式で、言語とは関係なく、プログラム設計思想です.
    OOP(オブジェクト指向プログラミング)POP(プロセス指向プログラミング)
    プロセスに向けて流れと計画を強調し、対象に向かって需要機能を垂直に異なるものに分割し、独立したものにして、異なる種類にカプセル化し、自分の行為をさせる.
    AOPのキーポイントは、汎用ロジックを業務ロジックから分離することです.
    運用する
    mavenのpom.xmlにaop依存を追加します.
    
        org.springframework.boot
        spring-boot-starter-aop
    
    
    第一の方法:
    sopを使って、コンソールでレコードのログ情報を出力します.
    @Aspect
    @Component
    public class BoyAspect {
        //      ,         ,     
        @Pointcut("execution(public * com.lfy.BoyController.*(..))")
        public void log() {}
    
    
        //     ,         execution
        @Before("log()")
        public void doBefore() {
            //   sop             
            System.out.println("doBefore");
        }
    
        //     
        @After("log()")
        public void doAfter() {
            System.out.println("doAfter");
        }
    }
    
    第二の方法:
    ロガーFactoryのget Logger法を用いてロガーオブジェクトを取得し、そのinfo方法を呼び出してコンソールに記録されたログ情報を出力する.
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    
    import javax.servlet.http.HttpServletRequest;
    
    @Aspect
    @Component
    public class BoyAspect {
        private final static Logger logger = LoggerFactory.getLogger(BoyAspect.class);
    
        @Pointcut("execution(public * com.lfy.BoyController.*(..))")
        public void log() {}
    
        @Before("log()")
        public void doBefore(JoinPoint joinPoint) {、
            //   HttpServletRequest  
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            //       
            // url
            logger.info("url={}", request.getRequestURI());
            //     
            logger.info("method={}", request.getMethod());
            //    ip  
            logger.info("ip={}", request.getRemoteAddr());
            //        (  JoinPoint   )
            logger.info("class.method={}", joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
            //           (  JoinPoint   )
            logger.info("args={}", joinPoint.getArgs());
        }
    
        //     
        @AfterReturning(pointcut="log()", returning = "object")
        public void doAfterReturning(Object object) {
            //       
            logger.info("response={}", object);
        }
    
        @After("log()")
        public void doAfter() {
            logger.info("doAfter");
        }
    } 
    
    統一異常処理
    フロントに送るデータフォーマットの統一
    カスタムResultクラスは、返ってきたdataデータのタイプが不明なため、汎型を使用します.
    public class Result {
        private Integer code;
        private String message;
        private T data;
        // ...
    }
    
    Resultツールクラス
    public class ResultUtil {
        //      data  
        public static Result success(Object object) {
            Result result = new Result();
            result.setCode(0);
            result.setMessage("  ");
            result.setData(object);
            return result;
        }
        //      data  
        public static Result success() {
            return success(null);
        }
    
        //   
        public static Result error(Integer code, String message) {
            Result result = new Result();
            result.setCode(code);
            result.setMessage(message);
            return result;
        }
    }
    
    統一異常処理例
    列挙類の使用は、セット方法がありません.列挙タイプは構造方法によって価値を与えられます.
    public enum ResultEnums {
        UNKNOWN_ERROR(-1, "    "),
        SUCCESS(0, "  "),
        PRIMARY_SCHOOL(101, "  "),
        MIDDLE_SCHOOL(102, "  ");
    
        private Integer code;
        private String message;
    
        ResultEnums(Integer code, String message) {
            this.code = code;
            this.message = message;
        }
    
        public Integer getCode() {
            return code;
        }
        public String getMessage() {
            return message;
        }
    }
    
    カスタム異常、ここでRuntimeExceptionを継承し、Exceptionを継承しないのは、springフレームがRuntimeExceptionに対してロールバックするからです.
    public class BoyException extends RuntimeException {
        private Integer code;
    
        public Integer getCode() {
            return code;
        }
    
        public void setCode(Integer code) {
            this.code = code;
        }
    
        //            
        public BoyException(ResultEnums resultEnums) {
            super(resultEnums.getMessage());
            this.code = resultEnums.getCode();
        }
    }
    
    異常処理類
    @Controller Adviceの注釈により、コントローラの全体構成を同じ位置に置くことができます.
    @Controller Adviceの類を注釈した方法は@Exception Handlerなどを使って方法に注釈を付けることができます.
    @Controller Adviceコメントは、@Request Mappingのコントローラをすべて注釈した方法に作用します.
    @Exception Handler:グローバルコントローラの異常処理に使用します.
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    @ControllerAdvice
    public class ExceptionHandle {
        private static final Logger logger = LoggerFactory.getLogger(ExceptionHandle.class);
    
        @ExceptionHandler(value=Exception.class)
        @ResponseBody
        public Result handle(Exception e) {
            if (e instanceof BoyException) {
                BoyException boyException = (BoyException) e;
                return ResultUtil.error(boyException.getCode(), boyException.getMessage());
            }
            logger.info("    ={}", e);
            return ResultUtil.error(-1, "    ");
        }
    }
    
    serviceはカスタム異常とエニュメレート・クラスを使用します.
    public void getAge(Integer id) throws Exception {
            Boy boy = boyRepository.findOne(id);
            Integer age = boy.getAge();
            if (age <= 10) {
                throw new BoyException(ResultEnums.PRIMARY_SCHOOL);
            } else if (age <= 16 ) {
                throw new BoyException(ResultEnums.MIDDLE_SCHOOL);
            }
        }
    
    controller,throws Exceptionは処理を異常に返した結果をフロントに返すようにします.
    @GetMapping(value="/boys/getAge/{id}")
    public void getAge(@PathVariable("id") Integer id) throws Exception {
        boyService.getAge(id);
    }
    
    ユニットテスト
    テストサービス
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class BoyServiceTest {
        @Autowired
        private BoyService boyService;
        
        @Test
        public void findAllBoy() throws Exception {
            List allBoy = boyService.findAllBoy();
            //           ,       ,       
            Assert.assertEquals(new Integer(7), allBoy.get(0).getAge());
        }
    }
    
    テスト結果は予想結果と一致しません.コンソールからの提示:1 test failed
    java.lang.Asertion Error:
    Expected:8
    Actual:7
    一致、提示:1 test passed
    APIをテストします
    @AutoConfigreMockMvcコメントを追加し、MockMvcオブジェクトを使ってテストを行います.
    @RunWith(SpringRunner.class)
    @SpringBootTest
    @AutoConfigureMockMvc
    public class BoyControllerTest {
        @Autowired
        private MockMvc mvc;
    
        @Test
        public void findAllBoy() throws Exception {
            //       
            mvc.perform(MockMvcRequestBuilders.get("/boys"))
                    //         200(  )
                    .andExpect(MockMvcResultMatchers.status().isOk())
                    //        
                    .andExpect(MockMvcResultMatchers.content().string("123"));
        }
    }