AspectJ简介
AspectJ是一个基于Java语言的AOP框架。从Spring2.0以后引入了AspectJ的支持。对于目前的Spring框架,建议开发者使用AspectJ实现SpringAOP。使用AspectJ实现SpringAOP的方式有两种,一种是基于XML配置开发AspectJ,二是基于注解开发AspectJ。
切入点表达式:execution (返回参数 包名.类名.方法名(参数))
例: execution(* *.*.*(..))
第一个*代表返回的类型(如果此处使用*则代表任何返回类型)
第二个*表示包名(此处使用*则代表任何包)
第三个*代表类(此处使用*则代表任何类)
第四个*代表方法(此处使用*则代表任方法)
括号中的值代表参数(..) 代表任何参数。
注意返回参数与包名之间有空格
1.基于XML配置开发AspectJ
配置XML文件定义切面、切入点及通知,所有的这些定义必须在 < aop:config>元素内。
aop:config 元素及其子元素
aop:config 开发AspectJ的顶层配置元素。
aop:aspect 配置一个切面,
aop:pointcut 配置切入点,属性expression指定通知增强哪些方法
aop:after配置后置通知
aop:after-returning配置后置返回通知
aop:after-throwing 配置异常通知
aop:around 配置环绕通知
aop:before 配置前置通知
aop:declare-parents 给通知引入新的额外接口,增强功能
如何实现
基于xml配置
1.编写切面
public class MyAspect {
// 前置通知,使用Joinpoint接口作为参数获得目标对象信息
public void before(JoinPoint jp) {
System.out.println("前置通知。。。");
}
// 后置返回通知,使用Joinpoint接口作为参数获得目标对象信息
public void afterReturning(JoinPoint jp) {
System.out.println("后置返回通知。。。");
}
// 环绕通知,ProceedingJoinPoint为可执行的目标方法
public Object around (ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕开始。。。");
Object o=pjp.proceed();
System.out.println("环绕结束。。。");
return o;
}
// 异常通知,使用Throwable接受异常信息
public void except (Throwable e) {
System.out.println("异常通知"+e.getMessage());
}
// 后置通知
public void after() {
System.out.println("最终通知。。。");
}
}
-
编写DAO与Service层
public interface TestDao { public void run(); } public class TestImpl implements TestDao { public void run() { System.out.println("run....."); } }
3.配置xml文件
<bean id="myAspect" class="MyAspect">
<bean id="testImpl" class="TesTImpl">
<aop:config>
<!-- 配置切面信息-->
<aop:aspect ref="myAspect">
<!-- 配置切入点,通知增强哪些方法 -->
<aop:pointcut expression="execution(* *.*.*(..))" id="myPointCut"/>
<!--关联 通知 -->
<aop:after method="after" pointcut-ref="myPointCut"/>
<aop:after-returning method="afterReturning" pointcut-ref="myPointCut"/>
<!--关联 异常通知 throwing属性设置通知的第二个参数名称 -->
<aop:after-throwing method="except" pointcut-ref="myPointCut" throwing="e"/>
<aop:around method="around" pointcut-ref="myPointCut" />
<aop:before method="before" pointcut-ref="myPointCut"/>
</aop:aspect>
</aop:config>
4.编写测试类
public class TestMain{
public static void main(String[] args) throws SQLException {
// TODO Auto-generated method stub
AbstractApplicationContext a=new ClassPathXmlApplicationContext("applicationcontext.xml");
TestDao t=(TestDaot)a.getBean("testImpl");
t.run();
a.close();
}
}
5.控制台显示
2.基于注解方式
1.注解切面
@Aspect
@Component
public class MyAspect {
//定义切入点 等于 <aop:pointcut expression="execution(* *.*.*(..))" id="myPointCut"/>
//id值即为方法名
//此方法为private类型!!!!
@Pointcut("execution(* *.*.*(..))")
private void pointcut() {
}
//此处的pointcut()即为切入点id(方法名)
@Before("pointcut()")
// 前置通知,使用Joinpoint接口作为参数获得目标对象信息
public void before(JoinPoint jp) {
System.out.println("前置通知。。。");
}
// 后置返回通知,使用Joinpoint接口作为参数获得目标对象信息
@AfterReturning("pointcut()")
public void afterReturning(JoinPoint jp) {
System.out.println("后置返回通知。。。");
}
// 环绕通知,ProceedingJoinPoint为可执行的目标方法
@Around("pointcut()")
public Object around (ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕开始。。。");
Object o=pjp.proceed();
System.out.println("环绕结束。。。");
return o;
}
// 异常通知,使用Throwable接受异常信息
@AfterThrowing(value = "pointcut()",throwing = "e")
public void except (Throwable e) {
System.out.println("异常通知"+e.getMessage());
}
// 后置通知
@After("pointcut()")
public void after() {
System.out.println("最终通知。。。");
}
}
2.在xml中开启配置并扫描包
<context:component-scan base-package="XXX"></context:component- scan>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
3.编写Dao与Service
4.编写测试类
5.运行结果与上面一致