多个切面执行顺序(请先看spring cache篇)

2018-01-11  本文已影响0人  多关心老人

代码https://github.com/HiwayChe/zheng/tree/develop/zheng-test

spring cache篇https://www.jianshu.com/p/b9e85a139ea0


Cache切面在事务切面前面,只有事务执行成功才往cache中缓存数据。
代码中共有4个切面,分别为获取缓存失效时间,设置缓存,切换数据源,事务。
执行顺序:CacheExpireAdvice.before->CacheInterceptor.invoke->MultiDataSourceAdvice.before->TransactionInterceptor.invode->MultiDataSourceAdvice.afterReturning->CacheExpireAdvice.afterReturning。
其中CacheInterceptor和TransactionInterceptor没有before,afterReturning之分。
afterReturning只有在方法成功后才执行,如果target中抛了异常,那么afterReturning是不会执行的。如TransactionInterceptor执行失败,CacheInterceptor是不会缓存数据的。


执行CacheTest4测试用例,日志解析如下:

@Test
    public void test(){
        String key = "fafaxxx";
        Account account;
        for(int i=0;i<2;i++){
            account = this.accountService.getAccountByName(key);
            try {
                this.logger.info("sleeping................");
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        this.accountService.update(key);
        this.logger.info("cache evicted....");
        for(int i=0;i<2;i++){
            account = this.accountService.getAccountByName(key);
            try {
                this.logger.info("sleeping................");
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

日志:

#执行CacheExpireAdvice.before方法,获取缓存失效时间
01-11 00:35:27 [main] INFO  CacheExpireAdvice.before() | CacheExpireAdvice before, target method:getAccountByName
#切换数据源
01-11 00:35:27 [main] INFO  DataSourceAdvice.before() | DataSourceAdvice before,target method:getAccountByName
#当前数据源是read
01-11 00:35:27 [main] INFO  MultiDataSource.determineCurrentLookupKey() | current database:read
#由于是第一次执行,缓存中没有数据,这里从db中查找
01-11 00:35:27 [main] INFO  AccountService.getFromDB() | =====================real querying db... fafaxxx
#清空数据源设置(到这里说明事务成功了)
01-11 00:35:27 [main] INFO  DataSourceAdvice.afterReturning() | DataSourceAdvice after,target method:getAccountByName
#db中查询的结果缓存起来,有失效时间的
01-11 00:35:27 [main] INFO  MyRedisCache.put() | cache with expire.....
#清空失效时间值
01-11 00:35:27 [main] INFO  CacheExpireAdvice.afterReturning() | CacheExpireAdvice after, target method:getAccountByName
#代码sleeping
01-11 00:35:27 [main] INFO  CacheTest4.test() | sleeping................
#第二次执行(这时缓存中有数据了),获取缓存失效值
01-11 00:35:30 [main] INFO  CacheExpireAdvice.before() | CacheExpireAdvice before, target method:getAccountByName
#由于缓存中有数据了,这里直接在CacheInterceptor中返回,不再走db。清空失效值
01-11 00:35:30 [main] INFO  CacheExpireAdvice.afterReturning() | CacheExpireAdvice after, target method:getAccountByName
#代码sleeping
01-11 00:35:30 [main] INFO  CacheTest4.test() | sleeping................
#进入到update方法(这个方法会清空缓存)。
01-11 00:35:33 [main] INFO  DataSourceAdvice.before() | DataSourceAdvice before,target method:update
#切换数据源到write
01-11 00:35:33 [main] INFO  MultiDataSource.determineCurrentLookupKey() | current database:write
01-11 00:35:33 [main] INFO  AccountService.update() | update or delete account from DB, evict from cache
#清空数据源设置
01-11 00:35:33 [main] INFO  DataSourceAdvice.afterReturning() | DataSourceAdvice after,target method:update
01-11 00:35:33 [main] INFO  CacheTest4.test() | cache evicted....
#再次读取数据,和最上面的一样了
01-11 00:35:33 [main] INFO  CacheExpireAdvice.before() | CacheExpireAdvice before, target method:getAccountByName
01-11 00:35:33 [main] INFO  DataSourceAdvice.before() | DataSourceAdvice before,target method:getAccountByName
01-11 00:35:33 [main] INFO  MultiDataSource.determineCurrentLookupKey() | current database:read
01-11 00:35:33 [main] INFO  AccountService.getFromDB() | =====================real querying db... fafaxxx
01-11 00:35:33 [main] INFO  DataSourceAdvice.afterReturning() | DataSourceAdvice after,target method:getAccountByName
01-11 00:35:33 [main] INFO  MyRedisCache.put() | cache with expire.....
01-11 00:35:33 [main] INFO  CacheExpireAdvice.afterReturning() | CacheExpireAdvice after, target method:getAccountByName
01-11 00:35:33 [main] INFO  CacheTest4.test() | sleeping................
01-11 00:35:36 [main] INFO  CacheExpireAdvice.before() | CacheExpireAdvice before, target method:getAccountByName
01-11 00:35:36 [main] INFO  CacheExpireAdvice.afterReturning() | CacheExpireAdvice after, target method:getAccountByName
01-11 00:35:36 [main] INFO  CacheTest4.test() | sleeping................
上一篇下一篇

猜你喜欢

热点阅读