通知类型
①前置通知(before):在目标方法执行之前进行操作
②后置通知(after-returning):在目标方法执行之后 进行操作
③环绕通知(around):在目标方法执行之前 和之后进行操作
public Object arount(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("开启事务");
Object proceed = joinPoint.proceed();
System.out.println("提交事务");
return proceed;
}
④异常抛出通知(after-throwing):在程序出现异常时进行操作
public void exceptionM(Throwable ex){
System.out.println("发生了异常:" + ex.getMessage());
}
⑤最终通知(after ):无论代码是否有异常,都会执行
使用
1.引入spring基本jar包
2.引入aop开发的相关jar包
3.配置文件中引入aop约束
<?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"
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.xsd">
</beans>
4.Spring测试
测试时,每次都需要获取工厂,通过spring-test,就不用每次获取,添加测试依赖包。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
5.测试
6.编写一个切面类
public class Myaspect {
public void check(){
System.out.println("权限校验!");
}
public void log(Object res){
System.out.println("日志记录!" + res);
}
public Object arount(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("开启事务");
Object proceed = joinPoint.proceed();
System.out.println("提交事务");
return proceed;
}
public void exceptionM(Throwable ex){
System.out.println("发生了异常:" + ex.getMessage());
}
public void after(){
System.out.println("最终通知");
}
}
7.将切面交给spring
8.配置AOP完成对目标产生代理
<?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"
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.xsd">
<bean id="goodsDao" class="pers.liuchengyin.demo1.GoodsDaoImpl"></bean>
<bean id="myaspect" class="pers.liuchengyin.demo2.Myaspect"></bean>
<!--配置Aop-->
<aop:config>
<!-- 切点:给哪个方法增强 -->
<aop:pointcut id="savepoint" expression="execution(* pers.liuchengyin.demo1.GoodsDaoImpl.save(..))"/>
<aop:pointcut id="updatepoint" expression="execution(* pers.liuchengyin.demo1.GoodsDaoImpl.update(..))"/>
<aop:pointcut id="deletepoint" expression="execution(* pers.liuchengyin.demo1.GoodsDaoImpl.delete(..))"/>
<aop:pointcut id="findpoint" expression="execution(* pers.liuchengyin.demo1.GoodsDaoImpl.find(..))"/>
<!-- 配置切面:增强的功能是什么 -->
<aop:aspect ref="myaspect">
<!-- 前置通知 -->
<aop:before method="check" pointcut-ref="savepoint"/>
<!-- 后置通知 -->
<aop:after-returning method="log" pointcut-ref="updatepoint" returning="res"/>
<!-- 环绕通知 -->
<aop:around method="arount" pointcut-ref="deletepoint"/>
<!-- 异常通知 -->
<aop:after-throwing method="exceptionM" pointcut-ref="findpoint" throwing="ex"/>
<!-- 最终通知 -->
<aop:after method="after" pointcut-ref="findpoint"/>
</aop:aspect>
</aop:config>
</beans>
AOP切入点表达式
基于execution函数完成
语法
【访问修饰符】 方法返回值 包名.类名.方法名(参数)
public pers.liuchengyin.demo2.GoodsDaoImpl.save(..) 参数为任意参数
* pers.liuchengyin.demo2.GoodsDaoImpl.save(..) *任意类型
* pers.liuchengyin.demo2.GoodsDaoImpl+.save(..) +当前类和子类
* pers.liuchengyin..*.*(..) pers.liuchengyin 包以及子包下面所有类的所有方法