一、简介
- AspectJ是一个基于Java语言的AOP框架
- Spring2.0以后新增了对AspectJ切点表达式支持
- @AspectJ 是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面
二、AspectJ通知类型
三、开发步骤
1、导包
先引入Spring框架开发的基本开发包
再引入Spring框架的AOP的开发包
spring的传统AOP的开发的包
spring-aop-4.2.4.RELEASE.jar
com.springsource.org.aopalliance-1.0.0.jar
aspectJ的开发包
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
spring-aspects-4.2.4.RELEASE.jar
2、创建spring的配置文件,引入aop的约束
<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">
3、编写切面类
/**
*
*AspectJ的通知
*
*/
public class MyAdvice {
/**
* 后置通知
* @param joinPoint
*/
public void before(JoinPoint joinPoint){
System.out.println("前置通知:"+joinPoint.getSignature().getName());
}
/**
* 后置通知 可以获取到方法的返回值
* res形参名需要在配置文件中进行配置 ; <aop:after-returning method="after" returning="res"/>
*/
public void after(JoinPoint joinPoint,Object res){
System.out.println("后置通知:"+res);
}
/**
* 异常通知
* e参数名需要配置: <aop:after-throwing method="afterthrowing" pointcut-ref="mycut" throwing="e"/>
* @param joinPoint
*/
public void afterthrowing(JoinPoint joinPoint,Exception e){
System.out.println("异常通知:"+e.getMessage());
}
/**
* 最终通知
* @param joinPoint
*/
public void afterFinal(JoinPoint joinPoint){
System.out.println("最终通知");
}
/**
* 环绕通知
*/
@SuppressWarnings("finally")
public Object around(ProceedingJoinPoint joinPoint){
Object proceed =null;
try {
//前置通知
System.out.println("前置通知-------");
//执行目标方法
proceed= joinPoint.proceed();
System.out.println("后置通知-------");
//后置通知
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
//异常通知
System.out.println("异常通知-------");
}
finally {
System.out.println("最终通知-------");
//最终通知
return proceed;
}
}
}
目标类:
public class UserServiceImpl implements UserService{
@Override
public void add() {
System.out.println("add");
}
@Override
public void delete() {
System.out.println("delete");
}
@Override
public void update() {
System.out.println("update");
}
@Override
public void query() {
System.out.println("query");
}
spring中的配置:
<!-- Spring的aop编程
1.引入aop相关的jar 4个
引入命名空间和约束
-->
<!-- 1.配置目标类 -->
<bean id="userService" class="spring_aspectj_4.UserServiceImpl"></bean>
<!-- 2.配置通知类 -->
<bean id="advice" class="spring_aspectj_4.MyAdvice"></bean>
<aop:config proxy-target-class="false">
<!-- 配置一个公共的切点 -->
<aop:pointcut expression="execution(* spring_aspectj_4.*.*(..))" id="mycut"/>
<aop:aspect ref="advice">
<aop:before method="before" pointcut-ref="mycut"/>
<aop:after-returning method="after" returning="res" pointcut-ref="mycut"/>
<aop:after-throwing method="afterthrowing" pointcut-ref="mycut" throwing="e"/>
<aop:after method="afterFinal" pointcut-ref="mycut" />
<aop:around method="around" pointcut-ref="mycut"/>
</aop:aspect>
</aop:config>
四、注解方式实现
1、替换bean
<!-- 1.配置目标类 -->
<bean id="userService" class="spring_aspectj_4.UserServiceImpl"></bean>
<!-- 2.配置通知类 -->
<bean id="advice" class="spring_aspectj_4.MyAdvice"></bean>
2、@Aspect声名了切面,代替<aop:aspect ref="advice">
3、替换公共切入点(简化引入切点)
前:
<!-- 配置一个公共的切点 -->
<aop:pointcut expression="execution(* spring_aspectj_4.*.*(..))" id="mycut"/>
后:
@Pointcut("execution(* spring_aspectj_anno_01.UserServiceImpl.*(..))")
public void myCut() {
}
完整切点类:
@Component
@Aspect
public class MyAdvice {
@Pointcut("execution(* spring_aspectj_anno_01.UserServiceImpl.*(..))")
public void myCut() {
}
/**
* 后置通知
* @param joinPoint
*/
@Before("myCut()")
public void before(JoinPoint joinPoint){
System.out.println("前置通知:"+joinPoint.getSignature().getName());
}
/**
* 后置通知 可以获取到方法的返回值
* res形参名需要在配置文件中进行配置 ; <aop:after-returning method="after" returning="res"/>
*/
@AfterReturning(value="myCut()",returning="res")
public void after(JoinPoint joinPoint,Object res){
System.out.println("后置通知:"+res);
}
/**
* 异常通知
* e参数名需要配置: <aop:after-throwing method="afterthrowing" pointcut-ref="mycut" throwing="e"/>
* @param joinPoint
*/
@AfterThrowing(value="myCut()",throwing="e")
public void afterthrowing(JoinPoint joinPoint,Exception e){
System.out.println("异常通知:"+e.getMessage());
}
/**
* 最终通知
* @param joinPoint
*/
@After("myCut()")
public void afterFinal(JoinPoint joinPoint){
System.out.println("最终通知");
}
/**
* 环绕通知
*/
@Around("execution(* spring_aspectj_anno_01.UserServiceImpl.*(..))")
@SuppressWarnings("finally")
public Object around(ProceedingJoinPoint joinPoint){
Object proceed =null;
try {
//前置通知
System.out.println("前置通知-------");
//执行目标方法
proceed= joinPoint.proceed();
System.out.println("后置通知-------");
//后置通知
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
//异常通知
System.out.println("异常通知-------");
}
finally {
System.out.println("最终通知-------");
//最终通知
return proceed;
}
}
}
spring配置文件:
配置头:
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
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/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
2、开启组件扫描
<context:component-scan base-package="spring_aspectj_anno_01"></context:component-scan>
3、开启AOP注解
<!-- 开启AOP注解 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>