一、配置文件与接口方式
1、前置通知
1.1、实现 MethodBeforeAdvice
接口并重写 before(Method method, Object[] args, Object target)
方法
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
/**
* 前置通知
*/
public class AddUserBefore implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("*********************前置通知*********************");
System.out.println("方法名:"+method.getName());
System.out.println("参数个数:"+method.getParameterCount());
System.out.println("参数个数:"+args.length);
System.out.println("对象:"+target.toString());
}
}
1.2、编写配置文件
<bean id="addUserBefore" class="aop.AddUserBefore"></bean>
<!-- 前置通知 -->
<aop:config>
<!-- 切入点 -->
<aop:pointcut id="pointcutBrfore" expression="execution(public boolean service.IAddUserService.addUser(entity.User))"/>
<!-- 切面与切入点连接关系 -->
<aop:advisor advice-ref="addUserBefore" pointcut-ref="pointcutBrfore"/>
</aop:config>
2、后置通知
2.1、实现 AfterReturningAdvice
接口并重写 afterReturning(Object returnValue, Method method, Object[] args, Object target)
方法
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
/**
* 后置通知
*/
public class AddUserAfterReturning implements AfterReturningAdvice {
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("*********************后置通知*********************");
System.out.println("返回值:"+returnValue);
System.out.println("方法名:"+method.getName());
System.out.println("参数个数:"+method.getParameterCount());
System.out.println("参数个数:"+args.length);
System.out.println("对象:"+target.toString());
}
}
2.2、编写配置文件
<bean id="AddUserAfterReturning" class="aop.AddUserAfterReturning"> </bean>
<!-- 后置通知 -->
<aop:config>
<aop:pointcut id="pointcutAfterReturning" expression="execution(public boolean service.IAddUserService.addUser(entity.User))"/>
<aop:advisor advice-ref="AddUserAfterReturning" pointcut-ref="pointcutAfterReturning"></aop:advisor>
</aop:config>
3、异常通知
3.1、实现 ThrowsAdvice
接口并重写 afterThrowing(Exception ex)
与afterThrowing(Method method, Object[] args, Object target, Exception ex)
方法中的一种
import org.springframework.aop.ThrowsAdvice;
import java.lang.reflect.Method;
/**
* 异常通知
*/
public class AddUserThrowing implements ThrowsAdvice {
/**
* 两种方只需重写其中一种
* @param ex
*/
public void afterThrowing(Exception ex){
System.out.println("*********************异常通知1*********************");
System.out.println("异常信息:"+ex.getMessage());
}
/**
* 两种方只需重写其中一种
* @param ex
*/
public void afterThrowing(Method method, Object[] args, Object target, Exception ex){
System.out.println("*********************异常通知2*********************");
System.out.println("方法名:"+method.getName());
System.out.println("参数个数:"+method.getParameterCount());
System.out.println("参数个数:"+args.length);
System.out.println("对象:"+target.toString());
System.out.println("异常信息:"+ex.getMessage());
}
}
3.2、编写配置文件
<bean id="addUserThrowing" class="aop.AddUserThrowing"></bean>
<!-- 异常通知 -->
<aop:config>
<aop:pointcut id="pointCutThrowing" expression="execution(public boolean service.IAddUserService.addUser(entity.User))"/>
<aop:advisor advice-ref="addUserThrowing" pointcut-ref="pointCutThrowing"></aop:advisor>
</aop:config>
4、环绕通知
4.1、实现 MethodInterceptor
接口并重写 invoke(MethodInvocation invocation)
方法
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/**
* 环绕通知
*/
public class AddUserAround implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("*********************环绕通知*********************");
Object proceed = null;
try {
System.out.println("*********************环绕通知>>>>前置通知*********************");
//执行方法
proceed = invocation.proceed();
System.out.println("*********************环绕通知>>>>后置通知*********************");
System.out.println("\n**********************************************************************************");
//执行方法的返回值
System.out.println("返回值:" +proceed);
System.out.println("方法名:" + invocation.getMethod().getName());
System.out.println("参数个数:" + invocation.getArguments().length);
System.out.println("对象:" + invocation.getThis());
}catch (Exception e){
System.out.println("*********************环绕通知>>>>异常通知*********************");
}
//可修改 proceed ,改变最终的返回结果
return proceed ;
}
}
4.2、编写配置文件
<bean id="addUserAround" class="aop.AddUserAround"></bean>
<!-- 环绕通知 -->
<aop:config>
<aop:pointcut id="pointCutAroud" expression="execution(public boolean service.IAddUserService.addUser(..))"/>
<aop:advisor advice-ref="addUserAround" pointcut-ref="pointCutAroud"></aop:advisor>
</aop:config>
二、Schema方式
1、创建通知类
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
public class AdviceSchema {
/**
* 前置通知
* @param joinPoint
*/
public void before(JoinPoint joinPoint){
System.out.println("********************注解----->前置通知******************");
System.out.println("方法名:"+joinPoint.getSignature().getName());
System.out.println("参数个数:"+joinPoint.getArgs().length);
System.out.println("对象:"+joinPoint.getThis());
System.out.println("对象:"+joinPoint.getTarget());
}
/**
* 后置通知
* @param joinPoint
* @param returnVal
*/
public void afterReturning(JoinPoint joinPoint,Object returnVal){
System.out.println("********************注解----->后置通知******************");
System.out.println("方法名:"+joinPoint.getSignature().getName());
System.out.println("参数个数:"+joinPoint.getArgs().length);
System.out.println("对象:"+joinPoint.getThis());
System.out.println("对象:"+joinPoint.getTarget());
System.out.println("返回值:"+returnVal);
}
/**
* 异常通知
*/
public void throwing(JoinPoint joinPoint,Exception ex){
System.out.println("********************注解----->异常通知******************");
System.out.println("方法名:"+joinPoint.getSignature().getName());
System.out.println("参数个数:"+joinPoint.getArgs().length);
System.out.println("对象:"+joinPoint.getThis());
System.out.println("对象:"+joinPoint.getTarget());
System.out.println("异常信息:"+ex.getMessage());
}
/**
* 环绕通知
* @param joinPoint
* @return
*/
public Object around(ProceedingJoinPoint joinPoint){
System.out.println("********************注解----->环绕通知******************");
try {
System.out.println("********************注解----->环绕通知----->前置通知******************");
Object proceed = joinPoint.proceed();
System.out.println("返回值:"+proceed);
System.out.println("方法名:"+joinPoint.getSignature().getName());
System.out.println("参数个数:"+joinPoint.getArgs().length);
System.out.println("对象:"+joinPoint.getThis());
System.out.println("对象:"+joinPoint.getTarget());
System.out.println("********************注解----->环绕通知----->后置通知******************");
}catch (Throwable e){
System.out.println("********************注解----->环绕通知----->异常通知******************");
}finally {
System.out.println("********************注解----->环绕通知----->最终通知******************");
}
return true;
}
/**
* 最终通知
* @param joinPoint
*/
public void after(JoinPoint joinPoint){
System.out.println("********************注解----->最终通知******************");
System.out.println("方法名:"+joinPoint.getSignature().getName());
System.out.println("参数个数:"+joinPoint.getArgs().length);
System.out.println("对象:"+joinPoint.getThis());
System.out.println("对象:"+joinPoint.getTarget());
}
}
2、配置Schema
<bean id="adviceSchema" class="aop.AdviceSchema"></bean>
<aop:config>
<aop:pointcut id="pointcut" expression="execution(public boolean service.IAddUserService.addUser(..))"/>
<aop:aspect ref="adviceSchema">
<!-- 前置通知 -->
<aop:before method="before" pointcut-ref="pointcut"></aop:before>
<!-- 后置通知 -->
<aop:after-returning method="afterReturning" returning="returnVal" pointcut-ref="pointcut"></aop:after-returning>
<!-- 异常通知 -->
<aop:after-throwing method="throwing" throwing="ex" pointcut-ref="pointcut"></aop:after-throwing>
<!-- 最终通知 -->
<aop:after method="after" pointcut-ref="pointcut"></aop:after>
<!-- 环绕通知 -->
<aop:around method="around" pointcut-ref="pointcut"></aop:around>
</aop:aspect>
</aop:config>
三、注解方式
1、配置扫描器与开启 AOP 支持
<!-- 扫描器:扫描 指定包中包含@Component、@Service、@Repository、@Controller 的类并将该类加入 IOC 容器中 -->
<context:component-scan base-package="entity,dao.impl,service,aop"/>
<!-- 开启aop自动代理 -->
<aop:aspectj-autoproxy/>
2、创建通知类
2.1、@Before(value = "advice()")
中的方法需要带括号
2.2、@AfterReturning(pointcut = "advice()",returning ="returnVal" )
中的 returning ="returnVal"
为后置通知的返回值参数名,修改 returnVal 无法改变最终的返回值
2.3、@AfterThrowing(pointcut = "advice()",throwing = "ex")
中的 throwing = "ex"
为 异常通知中的异常参数名
2.4、public Object around(ProceedingJoinPoint joinPoint)
环绕通知的参数类型不同于其他通知,参数类型为 ProceedingJoinPoint
;修改环绕通知中的Object proceed = joinPoint.proceed();
proceed 的值,可改变最终的返回结果
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* 注解形式的 AOP
*/
@Component
@Aspect
public class AdviceAnnotation {
//定义一个切入点
@Pointcut(value = "execution(public boolean service..*.*(..))")
public void advice(){}
/**
* 前置通知
* @param joinPoint
*/
@Before(value = "advice()")
public void before(JoinPoint joinPoint){
System.out.println("********************注解----->前置通知******************");
System.out.println("方法名:"+joinPoint.getSignature().getName());
System.out.println("参数个数:"+joinPoint.getArgs().length);
System.out.println("对象:"+joinPoint.getThis());
System.out.println("对象:"+joinPoint.getTarget());
}
/**
* 后置通知
* @param joinPoint
* @param returnVal
*/
@AfterReturning(pointcut = "advice()",returning ="returnVal" )
public void afterReturning(JoinPoint joinPoint,Object returnVal){
System.out.println("********************注解----->后置通知******************");
System.out.println("方法名:"+joinPoint.getSignature().getName());
System.out.println("参数个数:"+joinPoint.getArgs().length);
System.out.println("对象:"+joinPoint.getThis());
System.out.println("对象:"+joinPoint.getTarget());
System.out.println("返回值:"+returnVal);
}
/**
* 异常通知
*/
@AfterThrowing(pointcut = "advice()",throwing = "ex")
public void throwing(JoinPoint joinPoint,Exception ex){
System.out.println("********************注解----->异常通知******************");
System.out.println("方法名:"+joinPoint.getSignature().getName());
System.out.println("参数个数:"+joinPoint.getArgs().length);
System.out.println("对象:"+joinPoint.getThis());
System.out.println("对象:"+joinPoint.getTarget());
System.out.println("异常信息:"+ex.getMessage());
}
/**
* 最终通知
* @param joinPoint
*/
@After(value = "advice()")
public void after(JoinPoint joinPoint){
System.out.println("********************注解----->最终通知******************");
System.out.println("方法名:"+joinPoint.getSignature().getName());
System.out.println("参数个数:"+joinPoint.getArgs().length);
System.out.println("对象:"+joinPoint.getThis());
System.out.println("对象:"+joinPoint.getTarget());
}
/**
* 环绕通知
* @param joinPoint
* @return
*/
@Around(value = "advice()")
public Object around(ProceedingJoinPoint joinPoint){
System.out.println("********************注解----->环绕通知******************");
try {
System.out.println("********************注解----->环绕通知----->前置通知******************");
Object proceed = joinPoint.proceed();
System.out.println("返回值:"+proceed);
System.out.println("方法名:"+joinPoint.getSignature().getName());
System.out.println("参数个数:"+joinPoint.getArgs().length);
System.out.println("对象:"+joinPoint.getThis());
System.out.println("对象:"+joinPoint.getTarget());
System.out.println("********************注解----->环绕通知----->后置通知******************");
}catch (Throwable e){
System.out.println("********************注解----->环绕通知----->异常通知******************");
}finally {
System.out.println("********************注解----->环绕通知----->最终通知******************");
}
return true;
}
}