(1)jar包
AOP联盟规范:com.springsource.org.aopalliance-1.0.0.jar
spring aop实现:spring-aop-3.2.0.RELEASE.jar
aspectJ 框架的jar(实现、规范):com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
spring aspect 支持:spring-aspects-3.2.0.RELEASE.jar
(2)切入点表达式
(3)通知类型
-
AspectJ规定的通知类型不需要进行接口实现。通过配置文件确定类型。
-
常用的有五种
1、before:前置通知(应用:各种校验)在方法执行前执行,
如果通知抛出异常,阻止方法运行。
2、afterReturning:后置通知(应用:常规数据处理)
方法正常返回后执行,如果方法中抛出异常,通知无法执行。
必须在方法执行后才执行,所以可以获得方法的返回值。
3、around:环绕通知(应用:十分强大,可以做任何事情)
方法执行前后分别执行,可以阻止方法的执 行
4、afterThrowing:抛出异常通知(应用:包装异常信息)
方法抛出异常后执行,如果方法没有抛出异常,无法执行
5、after:最终通知(应用:清理现场)
方法执行完毕后执行,无论方法中是否出现异常
(3)基于XML的代码实现 (参照黑马的例程)
TeacherService.java接口类
package com.itheima.d_aspectj_xml;
public interface TeacherService {
public void addTeacher();
public String updateTeacher();
}
TeacherServiceImpl.java实现类
package com.itheima.d_aspectj_xml;
public class TeacherServiceImpl implements TeacherService {
@Override
public void addTeacher() {
System.out.println("d_aspect xml add teacher");
//int i = 1/0;
}
@Override
public String updateTeacher() {
System.out.println("d_aspect xml update teacher");
return "来来来";
}
}
MyAspect.java类
package com.itheima.d_aspectj_xml;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
/**
* 切面类,含多个通知
* @author <a>传智•左慈</a>
*
*/
public class MyAspect {
public void myBefore(JoinPoint joinPoint){
System.out.println("前置通知, 方法名称:" + joinPoint.getSignature().getName());
}
public void myAfterReturning(JoinPoint joinPoint,Object xxx){
System.out.println("后置通知, 返回值:" + xxx);
}
public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("前");
//必须执行目标方法
Object obj = joinPoint.proceed();
System.out.println("后");
return obj;
}
public void myAfterThrowing(JoinPoint joinPoint, Throwable e){
System.out.println("抛出异常通知, " + e.getMessage());
}
public void myAfter(){
System.out.println("最终");
}
}
beans.xml的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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">
<!-- 1 目标类 -->
<bean id="teacherServiceId" class="com.itheima.d_aspectj_xml.TeacherServiceImpl"></bean>
<!-- 2 切面类(多个通知) -->
<bean id="myAspect" class="com.itheima.d_aspectj_xml.MyAspect"></bean>
<!-- 3 aop编程
3.1特殊切面,配置一个通知 和 一个切入点
<aop:advisor advice-ref="一个通知" pointcut-ref="一个切入点"/>
3.2 就是切面,声明配置多个通知和多个切入点
<aop:aspect ref="">确定切面类,从而获得多个通知
-->
<aop:config>
<aop:aspect ref="myAspect">
<!-- 3.2 配置切入点 -->
<aop:pointcut expression="execution(* com.itheima.d_aspectj_xml.*.*(..))" id="myPonitCut"/>
<!-- 3.3 声明通知类型
#1 前置通知 , 目标方法之前执行。
* 第一个参数为JoinPoint,可以获得目标方法名等。
<aop:before method="myBefore" pointcut-ref="myPonitCut"/>
#2 后置通知,目标方法之后执行,可以获得返回值。 通过“returning”属性配置第二个参数的名称,获得返回值的,类型必须Object
* 第一个参数为:JoinPoint
* 第二个参数为:Object xxx
<aop:after-returning method="myAfterReturning" pointcut-ref="myPonitCut" returning="xxx"/>
#3 环绕通知, 目标方法前后
方法要求:public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{
执行目标方法:joinPoint.proceed();
<aop:around method="myAround" pointcut-ref="myPonitCut"/>
#4 抛出异常通知,目标方法出现异常时才执行。通过“throwing”属性配置第二个参数的名称,获得具体的异常信息,类型必须是Throwable
* 第一个参数为:JoinPoint
* 第二个参数为:Throwable e
<aop:after-throwing method="myAfterThrowing" pointcut-ref="myPonitCut" throwing="e"/>
-->
<aop:before method="myBefore" pointcut-ref="myPonitCut"/>
</aop:aspect>
</aop:config>
</beans>
TestApp.java单元测试类
package com.itheima.d_aspectj_xml;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestApp {
@Test
public void demo01(){
//获得目标类
String xmlPath = "com/itheima/d_aspectj_xml/beans.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
TeacherService teacherService = (TeacherService) applicationContext.getBean("teacherServiceId");
teacherService.addTeacher();
teacherService.updateTeacher();
}
}