-----------------------------------Spring AOP----------------------------------------
Spring AOP ,即面向切面编程。
Spring中AOP代理由Spring的IOC容器负责生成、管理,其依赖关系也由IOC容器负责管理。因此,AOP代理可以直接使用容器中的其它bean实例作为目标,这种关系可由IOC容器的依赖注入提供。
前提条件:将需要aop的类加入ioc容器,将切面类加入ioc容器
1). xml方式实现:
<?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"
xmlns:context="http://www.springframework.org/schema/context"
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-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 将扫描com.spring.busi包以及子包下的 带有@Controller,@Component,@Service,@Repository 的bean,纳入ioc容器 -->
<context:component-scan base-package="com.spring.framework"></context:component-scan>
<!-- 开始spring动态代理 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!-- spring aop xml配置方法 -->
<bean id="loggerAspect" class="com.spring.framework.Aop.LoggerAspect"></bean>
<aop:config>
<!-- 配置切点表达式 -->
<aop:pointcut expression="execution(public * com.spring.framework.Aop.CalculatorImpl.*(..))" id="pointcut"/>
<aop:aspect ref="loggerAspect">
<aop:before method="beforeMethod" pointcut="pointcut"/>
</aop:aspect>
</aop:config>
</beans>
2).注解方式实现
package com.spring.framework.Aop;
import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
//将该类声明为一个切面: 需要把类放入ioc容器@Component ,再声明一个切面@Aspect
@Component
@Aspect
public class LoggerAspect {
@Pointcut("execution(public * com.spring.framework.Aop.CalculatorImpl.*(..))")
public void pointcut(){
}
//声明该方法为前置通知:在目标方法之前执行
@Before("pointcut()")
public void beforeMethod(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
System.out.println("methodName :"+methodName);
System.out.println("beforeMethod ..");
}
//后置通知在目标方法执行后执行(无论是否发生异常,发生异常也会执行)
@After("pointcut()")
public void afterMethod(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
System.out.println("methodName :"+methodName);
System.out.println("afterMethod ..");
}
@AfterReturning(returning="result" , pointcut="pointcut()")
public void afterReturning(JoinPoint joinPoint, Object result){
String methodName = joinPoint.getSignature().getName();
System.out.println("methodName :"+methodName +", result:"+result);
}
/**
* 环绕通知需要携带参数ProceedingJoinPoint
* @param pjp
* @return
*/
@Around("pointcut()")
public Object AroundMethod(ProceedingJoinPoint pjd){
Object result = null;
String methodName = pjd.getSignature().getName();
try {
//前置通知
System.out.println("Before--methodName :"+methodName +", param :"+ Arrays.asList(pjd.getArgs()));
//执行目标方法
result=pjd.proceed();
//后置通知
System.out.println("After--methodName :"+methodName +", result :"+ result);
} catch (Throwable e) {
e.printStackTrace();
//异常通知
System.out.println("Exception--methodName :"+methodName +", exception :"+ e);
}
//后置通知
System.out.println("After--methodName :"+methodName +", ends ....");
return result;
}
}