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切面得執行同樣是一個棧式結構,先進後出