AOP介绍
意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术,是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
总结: Spring中的AOP 利用代理对象在不修改源代码的条件下,对方法进行扩展.
需要先编辑切面类
注解:
- @Aspect 标识当前类是一个切面
- @Pointcut 标识切入点表达式
- @Before 通知注解
- @EnableAspectJAutoProxy
切面 = 动态代理+方法的扩展 后期被AOP API封装
切面类
@Component //将此类交给spring
@Aspect //标记此类是一个切面类
public class TsAspect {
//切面=切面表达式+通知方法
@Pointcut("bean(userServiceImpl)")
public void pointCut(){
}
@Before("pointCut()")
public void before(){
System.out.println("我是前置通知");
}
}
4大通知注解 bean within execution
@Pointcut("bean(userServiceImpl)")
@Pointcut("within(com.jt.demo1.aop.service.UserServiceImpl)")
@Pointcut("within(com.jt.demo1.aop.service.*)") //多个
说明: bean/within 都是粗粒度的匹配,匹配的是类(类中还有方法/方法可以重载!!!)
@Pointcut(“execution(返回值类型 包名.类名.方法名(参数列表))”)
//要求: 拦截service.包下的所有的类,任意方法, 任意参数 返回值类型任意!!
@Pointcut("execution(* com.jt.demo2.service..*.*(..))")
@Pointcut("@annotation(com.jt.demo2.anno.Tx)")
使用下面定义的@Tx去定义方法
使用元注解 @Targer @Retention 定义@Tx
@Target(ElementType.METHOD) //注解对方法有效
@Retention(RetentionPolicy.RUNTIME) //运行期有效
public @interface Tx {
}
通知注解
前置通知 @Before 在目标方法运行前执行.
后置通知 @AfterReturning 可记录目标方法的返回值结果 * returning: 后置通知获取返回值的属性
异常通知 @AfterThrowing 异常通知: 目标方法执行时,抛出异常时,异常通知执行.
最终通知 @After 不管目标方法执行是否正确,都要执行. 一般不用
说明:前四大通知类型不能控制目标方法的运行,所以在使用时一般记录程序的运行状态.
环绕通知 @Around 环绕通知中必须添加参数,并且必须位于第一位
1.如果有下一个通知,则执行下一个通知, 2.如果没有下一个通知则执行目标方法
在目标方法执行前后都要运行, 只有环绕通知才可以控制目标方法是否运行. 使用最多的通知方法.
@Before("pointCut()")
public void before(){
System.out.println("我是前置通知");
}
@AfterReturning(value = "pointCut()",returning = "result")
public void afterreturning(Object result){
System.out.println("我是后置通知,返回值为"+result);
}
@AfterThrowing(value = "pointCut()",throwing = "exception")
public void afterthrowing(Exception exception){
System.out.println("目标方法异常信息"+exception.getMessage());
}
@After("pointCut()")
public void after(){
System.out.println("我是最终通知!!");
}
@Around("pointCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕通知开始");
Object proceed = joinPoint.proceed();
System.out.println("环绕通知结束");
return proceed;
}
关于连接点joinPoint的用法
说明: 当用户调用方法时,如果该方法被切入点表达式匹配.则Spring会为其对象创建代理.
则将这个方法称之为连接点
说明:
1.ProceedingJoinPoint只适用于环绕通知,因为只有环绕通知,才能控制目标方法的运行.
2.JoinPoint 适用于其它的四大通知类型,可以用来记录运行的数据.
3. ProceedingJoinPoint 中有特殊的方法proceed();
4. 如果使用"JoinPoint" 则必须位于参数的第一位