通知概念
前置通知
1. 在目标方法执行之前执行。
后置通知
1. 在目标方法执行之后执行
2. 可以获取目标方法的返回值
3. 当目标方法遇到异常,不执行
最终通知
1. 无论目标方法是否遇到异常都会执行,相当于代码中的finnaly
异常通知
1. 获取目标方法抛出的异常
环绕通知
1. 能够控制目标方法的执行
/**
* dao 接口
* @author w7
*
*/
public interface PersonDao {
public String savePerson();
}
/**
* dao 接口实现
* @author w7
*
*/
public class PersonDaoImpl implements PersonDao{
public String savePerson() {
System.out.println("save person");
return "aaaaa";
}
}
/**
* 切面 事务
* @author w7
*
*/
public class Transaction {
/**
* 前置通知
* JoinPoint
* 是连接点,代表一个方法,客户端调用哪个方法,哪个方法就是连接点
* 通过该参数,可以获取到连接点的一些信息
*/
public void beginTransaction(JoinPoint joinPoint){
//获取目标类
System.out.println("targetClass:"+joinPoint.getTarget());
//获取连接点的参数
System.out.println("args:"+joinPoint.getArgs());
//获取连接点的名称
System.out.println("methodName:"+joinPoint.getSignature().getName());
System.out.println("开启事务");
}
/**
* 后置通知
* JoinPoint 连接点
* Object val 接受目标方法的返回值
*/
public void commit(JoinPoint joinPoint,Object val){
System.out.println(val);
System.out.println("事务提交");
}
/**
* 最终通知
*/
public void finalyMethod(JoinPoint joinPoint){
System.out.println("finally method");
}
/**
* 异常通知
*/
public void throwingMethod(JoinPoint joinPoint,Throwable ex){
System.out.println(ex.getMessage());
}
/**
* 环绕通知
*/
public void aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("aaaa");
joinPoint.proceed();//执行目标方法
System.out.println("bbb");
}
}
<bean id="personDao" class="com.itheima09.spring.aop.xml.advoice.PersonDaoImpl"></bean>
<bean id="transaction" class="com.itheima09.spring.aop.xml.advoice.Transaction"></bean>
<aop:config>
<aop:pointcut
expression="execution(* com.itheima09.spring.aop.xml.advoice.PersonDaoImpl.*(..))"
id="perform"/>
<!--
切面
-->
<aop:aspect ref="transaction">
<!--
前置通知
-->
<!--
<aop:before method="beginTransaction" pointcut-ref="perform"/>
-->
<!--
后置通知
1、在目标方法执行之后执行
2、能够获取到目标方法的返回值
returning="val" val:和后置通知方法的接收参数名一样
3、如果目标方法遇到异常,则后置通知将不执行
-->
<!--
<aop:after-returning method="commit" pointcut-ref="perform" returning="val"/>
-->
<!--
最终通知
不管目标方法是否遇到异常,最终通知都将执行
-->
<aop:after method="finalyMethod" pointcut-ref="perform"/>
<!--
异常通知
获取目标方法抛出的异常
throwing="ex"和方法中的第二个参数的名称一致
-->
<aop:after-throwing method="throwingMethod" pointcut-ref="perform" throwing="ex"/>
<!--
环绕通知
能够控制目标方法的执行
-->
<aop:around method="aroundMethod" pointcut-ref="perform"/>
</aop:aspect>
</aop:config>
public class PersonTest {
@Test
public void testProxy(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
PersonDao personDao = (PersonDao)context.getBean("personDao");
personDao.savePerson();
}
}
//结果:
aaaa
save person
finally method
bbb