课程链接:

1    简析

1.1  advisor简析

2    代码演练

2.1  类似顾问通知实现:(代码演练中没有用到顾问标签)

 

 

 

1    简析

顾问:在通知的基础之上,在细化我们的aop切面!

通知和顾问都是切面的实现方式!
通知是顾问的一个属性!

顾问会通过我们的设置,将不同的通知,在不通过的时间点,把切面
织入到不同的切入点!

PointCutAdvisor接口!
比较常用的两个实现类:
NameMatchMethodPointcutAdvisor :根据切入点(主业务方法)名称织入切面!
RegexpMethodPointcutAdvisor :根据自定义的正则表达式织入切面!

正则表达式中常用的三个运算符
.   任意单个字符
+   表示字符出现一次或者多次
*   表示字符出现0次或者多次

1.1  advisor简析(更加灵活的配置切面,详细的可以参见2.1)

Advisor是Pointcut和Advice的配置器,它包括PointcutAdvice,是将Advice注入程序中Pointcut位置的代码

<aop:aspectj-autoproxy/>
<aop:config proxy-target-class="true">
<aop:pointcut id="servicePointcut"
expression="execution(* com.cpic..*Service.*(..))" />
<aop:advisor pointcut-ref="servicePointcut" advice-ref="txAdvice"
order="3" />
</aop:config>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" />
<tx:method name="insert*" />
<tx:method name="remove*" />
<tx:method name="save*" />
<tx:method name="update*" />
<tx:method name="delete*" />
<tx:method name="cancel*" />
<tx:method name="trans*" />
<tx:method name="commit*" />
<tx:method name="submit*" />
<tx:method name="issue*" />
<tx:method name="accept*" />
<tx:method name="underwrite*" />
<tx:method name="modify*" />
<tx:method name="calculate*" />
<tx:method name="copy*" />
<tx:method name="print*" />
<tx:method name="create*" />
<tx:method name="send*" />
<tx:method name="activate*" />
<tx:method name="generate*" />
<tx:method name="do*" />
<tx:method name="find*" read-only="true" />
<tx:method name="get*" read-only="true" />
<tx:method name="load*" read-only="true" />
<tx:method name="list*" read-only="true" />
<!-- log方法会启动一个新事务 -->
<tx:method name="log*" propagation="REQUIRES_NEW"
isolation="READ_COMMITTED" />
<!-- 如果通过java代码来进行分库判断,这里exeNewTS方法需要启动一个新事务 ,切换数据源时使用-->
<tx:method name="exeNewTS*" propagation="REQUIRES_NEW"
isolation="READ_COMMITTED" />
<!-- <tx:method name="exeNewTS*"/> -->
</tx:attributes>
</tx:advice>

2    代码演练

2.1  类似顾问通知实现:(代码演练中没有用到顾问标签)

测试类:

package com.imooc.test.aop;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner; import com.imooc.aop.schema.advisors.service.InvokeService;
import com.imooc.test.base.UnitTestBase; @RunWith(BlockJUnit4ClassRunner.class)
public class TestAOPSchemaAdvisors extends UnitTestBase { public TestAOPSchemaAdvisors() {
super("classpath:spring-aop-schema-advisors.xml");
} @Test
/**
* 1 这里问题的关键:在 ConcurrentOperationExecutor.java类中的try方法中
* 把正常的方法service.invoke() 和出现异常的方法service.invokeException() 进行对比
*
* 2 从xml传值 <property name="maxRetries" value="3"/>
*/
public void testSave(){
InvokeService service = super.getbean("invokeService");
service.invoke(); System.out.println("===================================================================================================================");
service.invokeException();
}
}

配置类:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"
> <!-- 扫描包 -->
<context:component-scan base-package="com.imooc.aop.schema"></context:component-scan> <!-- 配置aop -->
<aop:config>
<aop:aspect id="concurrentOperationRetry" ref="concurrentOperationExecutor">
<!-- 注意:此处有小空格 -->

      <aop:pointcut id="idempotentOperation" 

        expression="execution(* com.imooc.aop.schema.advisors.service.*.*(..)) " />

     <aop:around pointcut-ref="idempotentOperation" method="doConcurrentOperation"/>

    </aop:aspect>
</aop:config> <!-- 配置bean类 ,当下类作为通知类存在-->
<bean id="concurrentOperationExecutor" class="com.imooc.aop.schema.advisors.ConcurrentOperationExecutor">

    <property name="maxRetries" value="3"/>

    <property name="order" value="100"/>
</bean> </beans>

实体类:

package com.imooc.aop.schema.advisors.service;

import org.springframework.dao.PessimisticLockingFailureException;
import org.springframework.stereotype.Service; @Service
public class InvokeService { public void invoke() {
System.out.println("Invoke Service ....");
} public void invokeException(){
throw new PessimisticLockingFailureException(""
);
}
}

通知类:

package com.imooc.aop.schema.advisors;

import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.core.Ordered;
import org.springframework.dao.PessimisticLockingFailureException; public class ConcurrentOperationExecutor implements Ordered{ private static final int DEFAULT_MAX_RETRIES = 2; private int maxRetries = DEFAULT_MAX_RETRIES; private int order = 1; public int getMaxRetries() {
return maxRetries;
} public void setMaxRetries(int maxRetries) {
this.maxRetries = maxRetries;
} public int getOrder() {
return order;
} public void setOrder(int order) {
this.order = order;
} /**
* 通知对应的方法
* @param pjp
* @return
* @throws Throwable
*/
public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable{
int numAttempts = 0; //次数
PessimisticLockingFailureException lockFailureException;
do {
numAttempts++;
System.out.println("Try Times : "+numAttempts);
try {
return pjp.proceed();
} catch (PessimisticLockingFailureException e) {
lockFailureException =
e;
}

} while (numAttempts<=this.maxRetries);//次数递增,当小于常量(xml传入的次数)时
System.out.println("Try error:"+numAttempts);
return lockFailureException; } }

打印日志:

四月 20, 2019 3:01:36 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@45a5049a: startup date [Sat Apr 20 15:01:36 CST 2019]; root of context hierarchy
四月 20, 2019 3:01:36 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [spring-aop-schema-advisors.xml]
四月 20, 2019 3:01:36 下午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
Try Times :
Invoke Service ....
===================================================================================================================
Try Times :

Try Times :
2
Try Times :

Try Times
:
Try error:4

四月 20, 2019 3:01:37 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@45a5049a: startup date [Sat Apr 20 15:01:36 CST 2019]; root of context hierarchy

Spring课程 Spring入门篇 5-7 advisors的更多相关文章

  1. Spring Boot -01- 快速入门篇(图文教程)

    Spring Boot -01- 快速入门篇(图文教程) 今天开始不断整理 Spring Boot 2.0 版本学习笔记,大家可以在博客看到我的笔记,然后大家想看视频课程也可以到[慕课网]手机 app ...

  2. Spring实践系列-入门篇(一)

    本文主要介绍了在本地搭建并运行一个Spring应用,演示了Spring依赖注入的特性 1 环境搭建 1.1 Maven依赖 目前只用到依赖注入的功能,故以下三个包已满足使用. <properti ...

  3. Spring课程 Spring入门篇 6-3 ProxyFactoryBean及相关内容(下)

    1 解析 1.1 使用global advisors demo 1.2 jdk代理和cglib代理的选择 1.3 如何强制使用CGLIB实现AOP? 1.4 JDK动态代理和CGLIB字节码生成的区别 ...

  4. Spring课程 Spring入门篇 6-2 ProxyFactoryBean及相关内容(上)

    1 解析 1.1 类的方式实现各种通知需要实现的接口 1.2 创建Spring aop代理的优点及方法 1.3 代理控制切入点和通知的顺序的代码实现(具体完全实现,见代码2.1) 1.4 代理方式选择 ...

  5. Spring课程 Spring入门篇 7-2 Advice定义及实例

    1 解析 1.1 通知:after和afterreturning的区别 1.2 @RunWith 是什么? 2 代码演练 2.1 注解方式配置通知的两种方式 2.2 异常通知 2.3 非异常通知 1 ...

  6. Spring课程 Spring入门篇 5-2 配置切面aspect

    本节主要讲了在xml中配置切面的demo 1 解析 1.1 配置切面xml 1.2 配置切面xml 1.3 问:什么是动态代理? 2 代码演练 2.1 配置切面xml 1 解析 1.1 配置切面xml ...

  7. Spring课程 Spring入门篇 4-9 Spring bean装配之对jsr支持的说明

    1 解析 1.1 疑问:2.2去掉@resource注解,为什么不能赋值?不是有set方法了吗? 1.2 @resource注解版本支持 1.3 没有显式指定@resource的那么,默认名称从何获得 ...

  8. Spring课程 Spring入门篇 4-8 Spring bean装配之基于java的容器注解说明--基于泛型的自动装配

    1 解析 1.1 什么是泛型? 1.2 泛型有什么作用? 1.3 泛型装配样式? 2 代码演练 2.1 泛型应用 1 解析 1.1 什么是泛型? Java泛型设计原则:只要在编译时期没有出现警告,那么 ...

  9. Spring课程 Spring入门篇 4-7 Spring bean装配之基于java的容器注解说明--@Scope 控制bean的单例和多例

    1 解析 1.1 bean的单例和多例的应用场景 1.2 单例多例的验证方式 1.3 @Scope注解单例多例应用 2 代码演练 2.1 @Scope代码应用 1 解析 1.1 bean的单例和多例的 ...

随机推荐

  1. XMPP后台搭建

    XMPP的环境搭建 1.下载MySQL 登录myql官网,点击页面下面的按钮 然后安装. 2.安装MySQL图形化管理工具mysql-workbench 同样进入mysql的官网, 下载 http:/ ...

  2. np.random.normal()

    高斯分布(Gaussian Distribution)的概率密度函数(probability density function): \[ f(x)=\frac1{\sqrt{2\pi}\sigma}\ ...

  3. Navicat 导出sql文件和导入sql文件

    1.导出sql文件 (1)选择需要导出数据库表,右击--->转储为sql文件---->结构和数据 (2)会弹出如下界面,采用默认的数据表名,点击确认即可. 2.导入sql文件 (1)点击表 ...

  4. logback 发送邮件的类.

    类名 : SMTPAppenderBase方法名: sendBuffer

  5. 转载 Python 操作 MySQL 的正确姿势 - 琉璃块

    Python 操作 MySQL 的正确姿势 收录待用,修改转载已取得腾讯云授权 作者 |邵建永 编辑 | 顾乡 使用Python进行MySQL的库主要有三个,Python-MySQL(更熟悉的名字可能 ...

  6. my34_脚本冥等添加自动任务-mysql监控部署

    场景: 定义一套添加mysql监控的脚本,在mysql安装完毕后,一键执行添加监控   已有以下的等一系列命令可以读取mysql从库的延迟时间并推向influxdb,变化的部分为 -P 端口.-k k ...

  7. 在win7系统设置SQL Server2014 express为远程数据

    如何设置远程访问到SQLserver服务器(局域网内的设置) 1.首先,使用Windows+R键 输入services.msc 打开本地服务. *说明:①MSSQLSERVER是正式使用的SQL创建实 ...

  8. .net将List序列转为Json字符串

    将List类型转化为Json,是我们平常开发时最常见的了.在使用中,有很多种方法,也可以使用. 第一种 第三方组件:Newtonsoft.Json.dll //转化成Json Newtonsoft.J ...

  9. Java - 关于子类父类的向上转型,向下转型

    以下Animal为父类,Dog,Cat作为子类,分别继承Animal class Animal{ public void shout(){ System.out.println("叫了一声& ...

  10. 《大数据日知录》读书笔记-ch16机器学习:分布式算法

    计算广告:逻辑回归 千次展示收益eCPM(Effective Cost Per Mille) eCPM= CTR * BidPrice 优化算法 训练数据使用:在线学习(online learning ...