大白话就是把所有需要增强的方法放在一个类里,该类就是切面类.切面类包含了通知,通知就是需要增强的方法,aop通过切入点表达式让通知作用于指定目标方法的连接点上,可能是方法之前连接点,方法之后连接点.
一个切面中应该包含@Aspect,通知,切入点表达式,才能够作用在连接点上
切入点表达式的写法:
//第一个 * 代表权限修饰符,返回值
//第二个 * 代表该包下的所有的类
//第三个 * 代表该包下的所有的类的所有方法
//…代表任意的参数列表
//切入到com.sms.spring.aop包下的所有类的所有方法的前面
@Before(value = "execution(* com.sms.spring.aop.*.*(..)")
/*
@Before:前置通知,作用于方法执行之前
@After:后置通知,作用于finally里面
@AfterReturning返回通知,作用于方法执行之后,搭配切入点表达式returning
获取方法返回值的变量名,其中方法的形参必须和切入点的参数名一致,形参的类
型为Object,类型写错则该后置通知不会执行
@AfterReturning(value = "execution(*com.sms.spring.aop.*.*(..)",returning="result")
@AfterThrowing:异常通知,作用于方法有异常时,搭配切入点表达式throwing获取异常,其中方法的形参必须和切入点的参数名一致
@AfterThrowing(value="execution(*com.sms.spring.aop.*.*(..)",throwing = "e")
*/
spring在解析这个切入点表达式之后,执行前置|后置|返回通知时,会将方法的信息封装在JointPoint这个类中:
public void before(JoinPoint joinpoint) {
//joinPoint.getArgs():获取方法的参数
Object[] args = joinpoint.getArgs();
String methodName = joinpoint.getSignature().getName();
}
公共切入点写法:@Pointcut
@Pointcut(value="execution(* com.sms.spring.aop.*.*(..))")
public void test(){
}
公共切入点的使用:
@Before(value="test()")
定义切面作用的优先级:@Order(数字),值越小优先级越高
需要spring的四个核心jar(core,bean,context,expression)+aopalliance+spring-aop+cglib+spring-aspects+aspectjweaver
<?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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启组件扫描 -->
<context:component-scan base-package="com.sms.spring.aop"></context:component-scan>
<!-- 开启Asceptj的动态代理功能 -->
<aop:aspectj-autoproxy />
</beans>
给目标类添加@Component注解
给切面类添加@Component注解和@Aspect注解
@Before(value = "execution(* com.sms.spring.aop.*.*(..)")
public void before(JoinPoint joinpoint) {
//joinPoint.getArgs():获取方法的参数
}
其中必须得到接口对象,而非实现类对象,因为代理对象和实现类对象实现共同的接口.
ApplicationContext ac= new ClassPathXmlApplicationContext("aop.xml");
MathI mathI = context.getBean("mathImpl", MathI.class);
ApplicationContext ac= new ClassPathXmlApplicationContext("aop.xml");
MathI mathI = context.getBean("mathImpl", MathI.class);
mathI.method();