日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

自定义注解简单实现

發布時間:2024/4/13 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 自定义注解简单实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
package com.learn.annotation;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;// 事務注解 設置傳播行為 /*** 在前面加個Ext* 這個注解是干嘛的* 你們一定要知道* 它是事務注解* 定義好了之后* 在這里面其實有這幾個方法* 但是我今天可能用不到這幾個方法* 你們下去自己去封裝* 設置傳播行為* 具體怎么實現呢* 方法我就不寫了* 你們自己寫* 我們看看源碼里面是怎么寫的* 你們看一下* 源碼里面加了攔截權限* 把這些我們也copy過來* 因為這個代碼你們看的懂* { ElementType.METHOD, ElementType.TYPE }* 我們可以寫這兩個* 可以在方法上面加上這個注解* 可以在類上加上這個注解* 我們不允許在類上用* 我們這個注解不允許在類上面用* 只允許在方法上去玩了* @Retention(RetentionPolicy.RUNTIME)* 這個寫完之后我們再寫第二步* 跟著我的步驟來* 封裝手動事務* 這個是我昨天寫過的* 是不是這樣的* 我寫過的話就不寫了* 因為待會我們就會用到這段代碼的* * * * @author Leon.Sun**/ @Target({ ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) public @interface ExtTransaction {} package com.learn.transaction;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.stereotype.Component; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.interceptor.DefaultTransactionAttribute;// 編程事務(需要手動begin 手動回滾 手都提交) /*** 我們還原成昨天的* 否則到時會繞的* 這個是手動獲取事務* 手動begin* 手動commit和手動rollback* 這代碼你們有沒有印象* 昨天講過的* 我特意講過這段代碼的* 還手寫過這個事務的* 是不是這樣的* 這個代碼看不看得懂* 這個代碼不難* 只要別人調用begin方法我就去開啟一個事務* 如果要是調用commit和rollback* 去回滾或者提交* 現在看應該能夠看得懂* 這個昨天已經講過的* 這個其實沒有什么難的* 你們學過事務都知道的* 然后我們接著再怎么做呢* 我們核心是在具體如何掃包* 具體如何掃包的話* 那么這里面我不是要寫一個AOP了* * * * @author Leon.Sun**/ @Component //@Scope("prototype") // 每個事務都是新的實例 目的解決線程安全問題 多例子 public class TransactionUtils {// 全局接受事務狀態private TransactionStatus transactionStatus;// 獲取事務源@Autowiredprivate DataSourceTransactionManager dataSourceTransactionManager;// 開啟事務public TransactionStatus begin() {transactionStatus = dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute());return transactionStatus;}// 提交事務public void commit(TransactionStatus transaction) {dataSourceTransactionManager.commit(transaction);}// 回滾事務public void rollback() {dataSourceTransactionManager.rollback(transactionStatus);}} package com.learn.aop;import java.lang.reflect.Method;import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.TransactionStatus;import com.learn.annotation.ExtTransaction; import com.learn.transaction.TransactionUtils;// 自定義事務注解具體實現 /*** 我們自定義的事務注解具體實現* 然后在這里寫一下* 加上切面編程@Aspect* 在這里面怎么寫呢* 在這里還要加上@Component* 讓他注入到Spring的容器里面去* 這步寫完了之后* 我說過的* 你們說一下這是一個什么通知啊* 就是這個攔截方法的時候* 攔截所有方法的情況下* 什么通知* 你們想一想* 就是這步他能用什么通知* 肯定是環繞通知* 記住肯定是環繞通知* 不可能用到其他通知的* 肯定是用環繞* 那我把環繞代碼copy過來好吧* 我就不去寫了* 因為我昨天講過了* 是不是這樣的* 再寫的話就比較浪費時間了* 在這邊說一下* * * * @author Leon.Sun**/ @Aspect @Component public class AopExtTransaction {// 一個事務實例子 針對一個事務/*** 我們把自定義的手動事務copy過來* 再去@Autowired一下* */@Autowiredprivate TransactionUtils transactionUtils;// 使用異常通知進行 回滾事務/*** 我們現在是寫框架的話* 把它寫成全部的* "execution(* com.learn.service.*.*.*(..))"* 這是我要和你們去講一下的* 全部怎么寫* service.*.*.*(..)* 這個都理解吧* 我就不去說了* 我們找那個包下面的呢* 我們找這個包下面的* com.learn.service* 這步寫完了之后* 這邊的代碼就有點麻煩了* 怎么麻煩了* 這也是非常核心的代碼* * */@AfterThrowing("execution(* com.learn.service.*.*.*(..))")public void afterThrowing() {// 獲取當前事務進行回滾// TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();transactionUtils.rollback();}// 環繞通知 在方法之前和之后處理事情/*** 我們把這段代碼copy過來* 攔截到方法之后你們說一下* 我這邊就直接口說這個步驟* 步驟答出來可能會好理解點* 要不然直接這樣改的話可能會比較繞* 首先獲取到代理對象的方法* 第二步干嘛呢* 獲取該方法上是否加上注解* 是不是這樣的* 然后到第三步的時候* 你們想想到第三步怎么做* 如果存在事務注解* 是不是開啟這個事務* 然后到第四步干嘛* 調用目標代理對象方法* 到第五步怎么做你想想* 第五步的時候代理對象方法調用完畢的情況下* 他怎么做* 想想怎么做* 判斷該方法上是否加上注解* 這個我昨天已經說過了* 然后同樣道理* 第六步什么樣的呢* 如果存在注解* 你看我是寫的非常詳細的* 如果存在注解* 怎么樣呢* 是不是提交事務* 我們可以先把四步先寫出來* 獲取目標代理方法這個比較麻煩* 大家寫的時候可以直接去copy* 因為這里面的代碼可能會比較多* 然后你們不要看我們文檔里面的* 有些方法沒有必要記下來* 你只要知道怎么做就行了* 這是我要和你們說的* 所以這邊我和你們說一下* 這個你們不要去記* * * * * @param pjp* @throws Throwable*/@Around("execution(* com.learn.service.*.*.*(..))")public void around(ProceedingJoinPoint pjp) throws Throwable {// 1.獲取該方法上是否加上注解ExtTransaction extTransaction = getMethodExtTransaction(pjp);/*** 我們拿到事務注解之后呢* */TransactionStatus transactionStatus = begin(extTransaction);// 2.調用目標代理對象方法/*** 這個方法直接調用目標代理對象* 待會我們的代碼都會做重構* */pjp.proceed();// 3.判斷該方法上是否就上注解commit(transactionStatus);}private TransactionStatus begin(ExtTransaction extTransaction) {if (extTransaction == null) {return null;}// 2.如果存在事務注解,開啟事務/*** 開啟事務是不是到這里來了*/return transactionUtils.begin();}/*** 判斷是否加上注解了* 待會我會把整個代碼做個重構* 重構的話看起來就會舒服多了* 大家先忍耐一下* 做完了做重構* 否則你們不知道重構是怎么來的* 如果transactionStatus等于null說明了什么問題* 你們想一想* 我不需要給他開啟事務* 那我就不做任何操作* * * @param transactionStatus*/private void commit(TransactionStatus transactionStatus) {/*** 所以判斷不等于null的情況下* 走到這一步的話* 在方法上加上事務的注解了* 是不是這樣的* 這個時候我怎么辦* transactionUtils.commit* */if (transactionStatus != null) {/*** 5.如果存在注解,提交事務* 去提交這樣的一個事務*/transactionUtils.commit(transactionStatus);}}// 獲取方法上是否存在事務注解/*** 這段代碼直接copy過來* 我先給你們寫一下* 因為這段代碼比較長* 而且寫得話太浪費時間了* 而且這段代碼也沒有什么意義* 這段代碼其實是怎么樣的一個目的* 給大家說一下* 你們猜也猜得到干嘛用的呢* 相當于通過你的切入點* 獲取目標代理對象方法* 是不是這樣的* 我在下去寫代碼的時候* 你知道我是怎么知道這API的嗎* 這也是你們要記住的思路* 沒有必要把任何代碼都記住* 什么意思呢* 這段代碼我開始也不知道通過這段代碼可以獲取代理對象的方法* 我怎么做呢* 先腦海中有這個思路* 然后我直接百度去找* AOP里面是怎么去獲取代理對象的方法* 就是這樣的* 明白這個意思沒有* 千萬別說我下去把API記住* 記一輩子沒用的* 我們寫是寫幾個步驟核心的* 這是我要給你們講的* 這理不理解* 沒必要記住* 我之前自己下去找這個方法的時候* 我會找很長時間的* 那這個方法看不看得懂什么意思* 獲取你代理對象的方法* 我把userServiceImpl的add給AOP進行管理的情況下* 我們就可以去獲取這個方法* 這個都是能夠看得懂的* 如果這個看不懂那就說明有問題了* 獲取到之后* 然后怎么做呢* * * @param pjp* @return* @throws NoSuchMethodException* @throws SecurityException*/private ExtTransaction getMethodExtTransaction(ProceedingJoinPoint pjp)throws NoSuchMethodException, SecurityException {/*** 獲取目標代理對象方法*/String methodName = pjp.getSignature().getName();/*** 獲取目標代理對象*/Class<?> classTarget = pjp.getTarget().getClass();/*** 獲取目標對象類型*/Class<?>[] par = ((MethodSignature) pjp.getSignature()).getParameterTypes();/*** 獲取目標對象方法*/Method objMethod = classTarget.getMethod(methodName, par);/*** 就是獲取一下這個方法上有沒有加上@ExtTransaction注解* 是不是這樣的* 然后這個代碼寫完了之后呢* 然后ExtTransaction.class* 然后我們這邊拿到這個事務注解* */ExtTransaction extTransaction = objMethod.getDeclaredAnnotation(ExtTransaction.class);return extTransaction;}}

?

超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生

總結

以上是生活随笔為你收集整理的自定义注解简单实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。