Spring-AOP(面向切面编程)–day08
AOP个人理解:
在多个业务模块的过程中,存在相同的子环节,比如到银行存钱、取钱、查询余额都需要进行用户验证环节,而这三个事务的核心是各自的存取钱、查询余额操作,用户验证是这三个事务模块都需要完成的操作用户验证,那么可以将这三个模块都用需要使用的用户验证操作提取出来,单独存储,然后设置这个验证用户的使用时机。
对于切面两个字的理解:
理解成汉堡,面包中间切开(切面),可以往里面加火腿、鸡腿肉等等,火腿和鸡腿肉是另外做好然后再往里面加入。就算你什么都不往里面加,他还算是个汉堡(我也不知道算不算反正还能吃)。那火腿和鸡肉呢,你不要汉堡可能往馒头里面加。好差不多就是这个意思,反正我暂时是这么理解的。
一、基本流程
1)流程分析
上述存取钱、查询余额流程分析
话不多少上图
事务流程
切面分析
将这两个事务中重复出现的放入卡、输密码和取走卡提取出来,再根据切面位置(上面那条直线在对应时间从插入操作)。
2)代码实现
主要业务
@Component(value = "zhuyao")
public class Zhuyao {
public void cunqian()
{
System.out.println("存钱");
}
public void quqian()
{
System.out.println("取钱");
}
}
切面业务
@Component
@Aspect
public class DoSomethings {
@Before("execution(* SpringAOP.test.Zhuyao.cunqian())")
public void before(){
System.out.println("放卡输密码");
}
@After("execution(* SpringAOP.test.Zhuyao.cunqian())")
public void after(){
System.out.println("拿走卡");
}
}
xml配置
<context:component-scan base-package="SpringAOP.test" />
<aop:aspectj-autoproxy/>
测试
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
Zhuyao zy= (Zhuyao)applicationContext.getBean("zhuyao",Zhuyao.class);
zy.cunqian();
结果
放卡输密码
存钱
拿走卡
这里已经实现了对取钱业务的支持,那么存钱业务也想实现怎么做,也就是如何定义多个切点?
进行如下修改:
@Before("execution(* SpringAOP.test.Zhuyao.*())")//匹配Zhuyao类下的所有方法
//* SpringAOP.test.Zhuyao.*()
// execution 中可以通过通配符 设置方法的格式 格式为 返回值 方法全限定名() 这样理解
//另外Before() 中定义的切点方法可以用 || 连接来进行指定匹配
下面引用:原文地址
插入时间定义:
注解 | 说明 |
---|---|
@Before | 前置通知,在连接点方法前调用 |
@Around | 环绕通知,它将覆盖原有方法,但是允许你通过反射调用原有方法,后面会讲 |
@After | 后置通知,在连接点方法后调用 |
@AfterReturning | 返回通知,在连接点方法执行并正常返回后调用,要求连接点方法在执行过程中没有发生异常 |
@AfterThrowing | 异常通知,当连接点方法异常时调用 |
xml 配置说明
AOP元素 | 用途 | 备注 |
---|---|---|
aop:advisor | 定义 AOP 的通知其 | 一种很古老的方式,很少使用 |
aop:aspect | 定义一个切面 | —— |
aop:before | 定义前置通知 | —— |
aop:after | 定义后置通知 | —— |
aop:around | 定义环绕通知 | —— |
aop:after-returning | 定义返回通知 | —— |
aop:after-throwing | 定义异常通知 | —— |
aop:config | 顶层的 AOP 配置元素 AOP 的配置是以它为开始的 | |
aop:declare-parents | 给通知引入新的额外接口,增强功能 | —— |
aop:pointcut | 定义切点 | —— |
xml配置示例
<!-- 装配 Bean-->
<bean name="landlord" class="pojo.Landlord"/>
<bean id="broker" class="aspect.Broker"/>
<!-- 配置AOP -->
<aop:config>
<!-- where:在哪些地方(包.类.方法)做增加 -->
<aop:pointcut id="landlordPoint"
expression="execution(* pojo.Landlord.service())"/>
<!-- what:做什么增强 -->
<aop:aspect id="logAspect" ref="broker">
<!-- when:在什么时机(方法前/后/前后) -->
<aop:around pointcut-ref="landlordPoint" method="around"/>
</aop:aspect>
</aop:config>