【Java開發(fā)】Java熱門框架深入開發(fā)第5篇:二、AOP案例【附代碼文檔】

??????教程全知識點(diǎn)簡介:學(xué)習(xí)目標(biāo) 一、Spring簡介 2 初識Spring 3 Spring體系結(jié)構(gòu) 二、IOC和DI入門案例【重點(diǎn)】 五、Bean的生命周期【了解】 問題導(dǎo)入 1 生命周期相關(guān)概念介紹 2 代碼演示 3 Bean銷毀時(shí)機(jī) 六、依賴注入(DI配置) 1 依賴注入方式【重點(diǎn)】 2 依賴自動裝配【理解】 3 集合注入 今日目標(biāo) 一、第三方資源配置管理 1 管理DataSource連接池對象 2 加載properties屬性文件【重點(diǎn)】 四、Spring整合其他技術(shù)【重點(diǎn)】 二、AOP案例 1 案例-測量業(yè)務(wù)層接口萬次執(zhí)行效率 2 AOP切入點(diǎn)數(shù)據(jù)獲取 2 Spring事務(wù)角色【理解】 二、請求與響應(yīng) 1 請求映射路徑【重點(diǎn)】 2 請求參數(shù) 3 日期類型參數(shù)傳遞【重點(diǎn)】 4 響應(yīng) 三、REST風(fēng)格 1 REST簡介 2 RESTful入門案例 3 REST快速開發(fā)【重點(diǎn)】 今日內(nèi)容 一、SSM整合【重點(diǎn)】 1 SSM整合配置 三、異常處理器【理解】 1 異常介紹 2 異常處理器 一、分模塊開發(fā)與設(shè)計(jì) 1. 分模塊開發(fā)的意義 模塊拆分原則 2. 分模塊開發(fā)(模塊拆分) 二、依賴管理 1. 依賴傳遞 2. 可選依賴 4 可選依賴和排除依賴的區(qū)別 三、聚合與繼承 1. 聚合工程 3. 繼承關(guān)系 5. 聚合與繼承的區(qū)別 四、屬性管理 1. 屬性 2. 版本管理 五、多環(huán)境配置與應(yīng)用 1. 多環(huán)境配置作用 2. 跳過測試(了解) 六、私服 2. 私服倉庫分類 3. 資源上傳與下載 附件1:POM文件總體配置說明 一、MyBatisPlus簡介 1. 入門案例 二、標(biāo)準(zhǔn)數(shù)據(jù)層開發(fā) 2. Lombok插件介紹 四、DML編程控制 1. id生成策略控制(Insert) 2. 多記錄操作(批量Delete/Select) 3. 邏輯刪除(Delete/Update) 4. 樂觀鎖(Update)


??????????git倉庫code.zip 直接get:???https://gitlab.com/yiqing112/backend/-/blob/main/Java/Java熱門框架深入開發(fā)/note.md ???????

? 本教程項(xiàng)目亮點(diǎn)

?? 知識體系完整:覆蓋從基礎(chǔ)原理、核心方法到高階應(yīng)用的全流程內(nèi)容
?? 全技術(shù)鏈覆蓋:完整前后端技術(shù)棧,涵蓋開發(fā)必備技能
?? 從零到實(shí)戰(zhàn):適合 0 基礎(chǔ)入門到提升,循序漸進(jìn)掌握核心能力
?? 豐富文檔與代碼示例:涵蓋多種場景,可運(yùn)行、可復(fù)用
?? 工作與學(xué)習(xí)雙參考:不僅適合系統(tǒng)化學(xué)習(xí),更可作為日常開發(fā)中的查閱手冊
?? 模塊化知識結(jié)構(gòu):按知識點(diǎn)分章節(jié),便于快速定位和復(fù)習(xí)
?? 長期可用的技術(shù)積累:不止一次學(xué)習(xí),而是能伴隨工作與項(xiàng)目長期參考


??????全教程總章節(jié)


??????本篇主要內(nèi)容

二、AOP案例

1 案例-測量業(yè)務(wù)層接口萬次執(zhí)行效率

問題導(dǎo)入

能不能描述一下環(huán)繞通知里面的實(shí)現(xiàn)步驟?

1.1 需求和分析

需求:任意業(yè)務(wù)層接口執(zhí)行均可顯示其執(zhí)行效率(執(zhí)行時(shí)長)

分析:

①:業(yè)務(wù)功能:業(yè)務(wù)層接口執(zhí)行前后分別記錄時(shí)間,求差值得到執(zhí)行效率
②:通知類型選擇前后均可以增強(qiáng)的類型——環(huán)繞通知

1.2 代碼實(shí)現(xiàn)

【前置工作】環(huán)境準(zhǔn)備
  1. Spring整合mybatis對spring_db數(shù)據(jù)庫中的Account進(jìn)行CRUD操作

  2. Spring整合Junit測試CRUD是否OK。

  3. 在pom.xml中添加aspectjweaver切入點(diǎn)表達(dá)式依賴

  4. ... ...

【第一步】編寫通知類
@Component
@Aspect
public class ProjectAdvice {
    //匹配業(yè)務(wù)層的所有方法
    @Pointcut("execution(* com.itheima.service.*Service.*(..))")
    private void servicePt(){}

    //設(shè)置環(huán)繞通知,在原始操作的運(yùn)行前后記錄執(zhí)行時(shí)間
    @Around("ProjectAdvice.servicePt()") //本類類名可以省略不寫
    public void runSpeed(ProceedingJoinPoint pjp) throws Throwable {
        //獲取執(zhí)行的簽名對象
        Signature signature = pjp.getSignature();
        //獲取接口/類全限定名
        String className = signature.getDeclaringTypeName();
        //獲取方法名
        String methodName = signature.getName();
        //記錄開始時(shí)間
        long start = System.currentTimeMillis();
        //執(zhí)行萬次操作
        for (int i = 0; i < 10000; i++) {
           pjp.proceed();
        }
        //記錄結(jié)束時(shí)間
        long end = System.currentTimeMillis();
        //打印執(zhí)行結(jié)果
        System.out.println("萬次執(zhí)行:"+ className+"."+methodName+"---->" +(end-start) + "ms");
    }
}
【第二步】在SpringConfig配置類上開啟AOP注解功能
@Configuration
@ComponentScan("com.itheima")
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class,MybatisConfig.class})
@EnableAspectJAutoProxy //開啟AOP注解功能
public class SpringConfig {
}
【第三步】運(yùn)行測試類,查看結(jié)果
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class AccountServiceTestCase {
    @Autowired
    private AccountService accountService;
    @Test
    public void testFindById(){
        Account account = accountService.findById(2);
    }
    @Test
    public void testFindAll(){
        List<Account> list = accountService.findAll();
    }
}

Apache HttpClient 文檔

2 AOP切入點(diǎn)數(shù)據(jù)獲取

問題導(dǎo)入

在環(huán)繞通知中可以獲取到哪些數(shù)據(jù)?

2.1 獲取參數(shù)

說明:在前置通知和環(huán)繞通知中都可以獲取到連接點(diǎn)方法的參數(shù)們

  • JoinPoint對象描述了連接點(diǎn)方法的運(yùn)行狀態(tài),可以獲取到原始方法的調(diào)用參數(shù)

Helidon 文檔

@Before("pt()")
public void before(JoinPoint jp) {
    Object[] args = jp.getArgs(); //獲取連接點(diǎn)方法的參數(shù)們
    System.out.println(Arrays.toString(args));
}
  • ProccedJointPoint是JoinPoint的子類
@Around("pt()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
    Object[] args = pjp.getArgs(); //獲取連接點(diǎn)方法的參數(shù)們
    System.out.println(Arrays.toString(args));
    Object ret = pjp.proceed();
    return ret;
}

2.2 獲取返回值

說明:在返回后通知和環(huán)繞通知中都可以獲取到連接點(diǎn)方法的返回值

  • 拋出異常后通知可以獲取切入點(diǎn)方法中出現(xiàn)的異常信息,使用形參可以接收對應(yīng)的異常對象
@AfterReturning(value = "pt()",returning = "ret")
public void afterReturning(String ret) { //變量名要和returning="ret"的屬性值一致
    System.out.println("afterReturning advice ..."+ret);
}
  • 環(huán)繞通知中可以手工書寫對原始方法的調(diào)用,得到的結(jié)果即為原始方法的返回值
@Around("pt()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
    // 手動調(diào)用連接點(diǎn)方法,返回值就是連接點(diǎn)方法的返回值
    Object ret = pjp.proceed();
    return ret;
}

2.3 獲取異常

說明:在拋出異常后通知和環(huán)繞通知中都可以獲取到連接點(diǎn)方法中出現(xiàn)的異常

  • 拋出異常后通知可以獲取切入點(diǎn)方法中出現(xiàn)的異常信息,使用形參可以接收對應(yīng)的異常對象

Redis Java 客戶端 Jedis

@A

## 三、Spring事務(wù)管理

### 1 Spring事務(wù)簡介【重點(diǎn)】

#### 問題導(dǎo)入

Spring提供的事務(wù)管理是數(shù)據(jù)層的事務(wù)還是業(yè)務(wù)層的事務(wù)?

#### 1.1 Spring事務(wù)作用

- 事務(wù)作用:在數(shù)據(jù)層保障一系列的數(shù)據(jù)庫操作同成功同失敗
- Spring事務(wù)作用:在數(shù)據(jù)層或**==業(yè)務(wù)層==**保障一系列的數(shù)據(jù)庫操作同成功同失敗

![](https://upload-images.jianshu.io/upload_images/29644671-6045f1ddbab67aa1.png)

#### 1.2 需求和分析

- 需求:實(shí)現(xiàn)任意兩個(gè)賬戶間轉(zhuǎn)賬操作
- 需求微縮:A賬戶減錢,B賬戶加錢
- 分析:
  ①:數(shù)據(jù)層提供基礎(chǔ)操作,指定賬戶減錢(outMoney),指定賬戶加錢(inMoney)
  ②:業(yè)務(wù)層提供轉(zhuǎn)賬操作(transfer),調(diào)用減錢與加錢的操作
  ③:提供2個(gè)賬號和操作金額執(zhí)行轉(zhuǎn)賬操作
  ④:基于Spring整合MyBatis環(huán)境搭建上述操作
- 結(jié)果分析:
  ①:程序正常執(zhí)行時(shí),賬戶金額A減B加,沒有問題
  ②:程序出現(xiàn)異常后,轉(zhuǎn)賬失敗,但是異常之前操作成功,異常之后操作失敗,整體業(yè)務(wù)失敗

#### 1.3 代碼實(shí)現(xiàn)

##### 【前置工作】環(huán)境準(zhǔn)備

> Spring整合Mybatis相關(guān)代碼(依賴、JdbcConfig、MybatisConfig、SpringConfig)省略。

```java
public interface AccountDao {

    @Update("update tbl_account set money = money + #{money} where name = #{name}")
    void inMoney(@Param("name") String name, @Param("money") Double money);

    @Update("update tbl_account set money = money - #{money} where name = #{name}")
    void outMoney(@Param("name") String name, @Param("money") Double money);
}

public interface AccountService {
    /**
     * 轉(zhuǎn)賬操作
     * @param out 傳出方
     * @param in 轉(zhuǎn)入方
     * @param money 金額
     */
    public void transfer(String out,String in ,Double money) ;
}

@Service
public class AccountServiceImpl implements AccountService {
    @Autowired
    private AccountDao accountDao;

    public void transfer(String out,String in ,Double money) {
        accountDao.outMoney(out,money);
        int i = 1/0;
        accountDao.inMoney(in,money);
    }

[Vaadin 文檔](https://vaadin.com/docs)


[Checkstyle 文檔](https://checkstyle.sourceforge.io/)

}
【第一步】在業(yè)務(wù)層接口上添加Spring事務(wù)管理
public interface AccountService {
    //配置當(dāng)前接口方法具有事務(wù)
    @Transactional
    public void transfer(String out,String in ,Double money) ;
}

注意事項(xiàng)

  1. Spring注解式事務(wù)通常添加在業(yè)務(wù)層接口中而不會添加到業(yè)務(wù)層實(shí)現(xiàn)類中,降低耦合
  2. 注解式事務(wù)可以添加到業(yè)務(wù)方法上表示當(dāng)前方法開啟事務(wù),也可以添加到接口上表示當(dāng)前接口所有方法開啟事務(wù)
【第二步】設(shè)置事務(wù)管理器(將事務(wù)管理器添加到IOC容器中)

說明:可以在JdbcConfig中配置事務(wù)管理器

//配置事務(wù)管理器,mybatis使用的是jdbc事務(wù)
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
    DataSourceTransactionManager dtm = new DataSourceTransactionManager();
    transactionManager.setDataSource(dataSource);
    return transactionManager;
}

注意事項(xiàng)

  1. 事務(wù)管理器要根據(jù)實(shí)現(xiàn)技術(shù)進(jìn)行選擇
  2. MyBatis框架使用的是JDBC事務(wù)
【第三步】開啟注解式事務(wù)驅(qū)動
@Configuration
@ComponentScan("com.itheima")
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class,MybatisConfig.class})
//開啟注解式事務(wù)驅(qū)動
@EnableTransactionManagement
public class SpringConfig {
}
【第四步】運(yùn)行測試類,查看結(jié)果

[FastJSON 文檔](https://github.com/alibaba/fastjson)

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class AccountServiceTest {

    @Autowired
    private AccountService accountService;

    @Test
    public void testTransfer() throws IOException {
        accountService.transfer("Tom","Jerry",100D);
    }
}

2 Spring事務(wù)角色【理解】

問題導(dǎo)入

什么是事務(wù)管理員,什么是事務(wù)協(xié)調(diào)員?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容