1. 程式人生 > 實用技巧 >springboot開啟全域性熱部署和切面程式設計

springboot開啟全域性熱部署和切面程式設計

1、在不重新啟動程式(伺服器)就可以將程式碼的修改立即生效的熱部署過程(原理就是配置了倆個類載入器,相互切換。也又代價,啟動會慢,因為現在要維護倆個類載入器)

2、springboot官方提供了倆種方式

  a.springboot-devtools 第一種方式

  b.spring-loaded 第二種方式,有時候不生效

  c.jrebel 第三方形式 jvm記憶體佔用少 修改之後立即生效無需等待 價格很貴

3、springboot如何開啟全域性熱部署

  a)引入依賴

  

<!--      熱部署的依賴-->
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-devtools</artifactId>
          <optional>true
</optional> </dependency>

   b).開啟idea的自動編譯功能

  在Compiler中勾選Build project automatically

  c).開啟idea中允許在程式執行過程允許交換器類載入

  ctrl+alt+shift+/ 選擇1.Registry----》勾選compiler.automake.allow.when.app.running這個選項

  d).重新啟動專案即可

二:springboot中切面程式設計

  1.Spring提出AOP面向切面程式設計

    AOP:就是通過動態為專案中某些類在執行過程中動態建立代理物件,然後再代理物件中完成附加功能和額外功能。保證再處理業務時更專注於自己得業務邏輯開發。

    概念:

      1).通知(advice) 除了目標方法以外操作稱之為通知 日誌通知 效能通知 事務通知.....

      2). 切入點(pointcut):用來告訴專案中那些類中那些方法在執行過程中加入通知

      3)切面(Aspect):通知 +切入點

  spring中AOP程式設計

    1).前置通知,後置通知,環繞通知,異常通知

    2).配置通知並組裝切面

      <bean id class="xxxxxx">

      <aop:config>

       <aop:pointcut expression = "exection()|within | annotation|args">

       <aop: advisor advice-ref="" pointcut-ref="" order=“1”>

      <aop: advisor advice-ref="" pointcut-ref="" order=“2”> 這裡得order值越小得越先執行 數字相同,配置先行

      <aop: advisor advice-ref="" pointcut-ref="" order=“2”>      

      </aop:config>

  springboot中得切面程式設計 

    a.引入spring-boot-starter-aop

    面向切面程式設計相關注解:

    @Aspect 註解 :修飾範圍在一個類上  作用:代表這個類是一個切面得配置類,相當aop:config標籤

@order註解 :修飾範圍只能用在類上 作用:用來控制多個切面執行順序 value屬性:int型別 數字越小越優先執行 (所以要想不同就必須重新寫一個類檔案)

   通知相關注解:

  修飾範圍:用在方法上 作用:代表這個方法是一個通知方法

    value屬性:用來書寫當前通知對應得切入點表示式

    @Before 前置通知

    

//這是一個切面配置類
@Component
@Aspect
public class MyAspect {

    //前置通知
//    @Before(value="execution(* com.chinaunicom.service..*ServiceImpl.*(..))")
    @Before(value="within(com.chinaunicom.service.*ServiceImpl)")
public void before147(JoinPoint joinPoint){
System.out.println("當前執行方法名:"+joinPoint.getSignature().getName());
System.out.println("當前執行方法引數:"+joinPoint.getArgs()[0]);
System.out.println("目標物件target:"+joinPoint.getTarget());
 System.out.println("===========進入前置通知=========="); 
} }

    @After 後置通知

    @Around 環繞通知

類級別得:

  

  @Before(value="within(com.chinaunicom.service.*ServiceImpl)")

   方法級別得:修飾於方法 

    @Before(value="execution(* com.chinaunicom.service..*ServiceImpl.*(..))")

  @Before和@After 獲取執行時方法得相關資訊在自定義通知方法中加入JointPoint引數,這個引數可以得到當前執行類得很多東西。
引數1:jointpoint 獲取當前執行物件 方法得引數資訊 以及目標物件
//後置通知
//    @Before(value="execution(* com.chinaunicom.service..*ServiceImpl.*(..))")
//    @After(value="within(com.chinaunicom.service.*ServiceImpl)")
//    public void after147(JoinPoint joinPoint) {
//        System.out.println("當前執行方法名:" + joinPoint.getSignature().getName());
//        System.out.println("當前執行方法引數:" + joinPoint.getArgs());
//        System.out.println("目標物件target:" + joinPoint.getTarget());
//        System.out.println("===========進入後置通知==========");
//
//    }
//    //前置通知
////    @Before(value="execution(* com.chinaunicom.service..*ServiceImpl.*(..))")
//    @Before(value="within(com.chinaunicom.service.*ServiceImpl)")
//    public void before147(JoinPoint joinPoint){
//        System.out.println("當前執行方法名:"+joinPoint.getSignature().getName());
//        System.out.println("當前執行方法引數:"+joinPoint.getArgs());
//        System.out.println("目標物件target:"+joinPoint.getTarget());
//        System.out.println("===========進入前置通知==========");

//    }




@Around 獲取執行時方法得相關資訊並且可以放行當前方法繼續執行,它的引數需要再環繞通知方法中宣告這個引數是ProceedingJointPoint
  
//環繞通知  執行目標方法之前進入環繞通知,環繞通知放行之後  才會執行目標方法 執行完成目標方法之後 再回到環繞通知
    @Around("within(com.chinaunicom.service.*ServiceImpl)")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

        System.out.println("==============目標方法執行之前進入環繞通知===================");
        System.out.println("方法名:"+proceedingJoinPoint.getSignature().getName());
        System.out.println("引數:"+proceedingJoinPoint.getArgs());
        System.out.println("目標物件:"+proceedingJoinPoint.getTarget());
        //放行目標方法  返回一個結果
        try {
            Object proceed = proceedingJoinPoint.proceed(); //放行執行目標方法
            System.out.println("==============目標方法執行之後進入環繞通知===================");
            return proceed;
        }catch (Exception e){
            System.out.println("目標方法出現異常時處理");
            return null;
        }

springboot多個切面執行順序

  在前置通知中order越小越優先,而後置通知得話就會相反

  注意:多個aop切面得執行同樣是一個棧式結構,先進後出