spring入门自学笔记(二)-AOP

AOP
1.开启aop的步骤演示:
1.开启AOP配置,使用注解 @EnableAspectJAutoProxy
@Configuration
@ComponentScan(basePackages = {"com.yyq"})
@EnableAspectJAutoProxy
public class SpringConfig {
}
2.被增强类不需要做任何操作(因为AOP的优点之一就是不侵犯原代码)
3.增强方法:

​ 1.创建一个类,类上使用注解@Aspect,说明是增强类

​ 2.类中创建方法,方法上使用注解@Before,@After…(如下),说明是增强方法

​ 3.在Before的value参数中写明切点表达式,切点表达式写法:

​ 规定: execution([权限修饰符][返回类型][类全路径][方法名称][参数列表])

​ 例如: execution(* com.yyq.service.impl.UserserviceImpl.say(…))

​ 说明: * 表示任意的权限修饰符,返回类型给个空格即可. 类全路径,大概类比一下,下面有更详细举例.

切点表达式写法:

由于Aspect本身并不属于spring,他是一个独立的开源项目, 所以他的语法稍显怪异, 但咱们只管应用于实际,根据框架规则去走即可.举如下几个常用例子可供参考:

任意公共方法的执行:execution(public * *..))
任何一个名字以“set”开始的方法的执行:execution(* set*..))
UserService接口定义的任意方法的执行:execution(* com.yyq.service.UserService.*(..))
在service包中定义的任意方法的执行:execution(* com.yyq.service.*.*(..))
在service包或其子包中定义的任意方法的执行:execution(* com.yyq.service..*.*(..))
@Component
@Aspect()
public class Log {
    
    @Before(value = "execution(* com.yyq.service.impl.UserserviceImpl.say(..))")
    public void  strongBefore(){
        System.out.println("事前加强");
    }
}

五个注解:

  • @Before 前置通知,在被增强方法之前执行
  • @After 后置(最终)通知,在被增强方法执行完毕后,return之前执行(类似finally,抛异常也会执行)
  • @AfterReturning 返回通知,在被增强方法返回值之后,return之后执行.(抛异常就不会继续执行)
  • @Around 环绕通知,可自行配置, 在方法参数出引入point***
  • @AfterThrowing 异常通知, 在方法抛异常之后执行

其中较特殊的是@Around环绕通知,因为他需要在方法的前后分别进行增强,还得执行原方法逻辑,下面举例说明

@Component
@Aspect()
public class Log {
    @Around(value = "execution(* com.yyq.service.impl..*(..))")
    public void strongAround(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("环绕前置通知............");
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();//拓展:代表切面方法,强转后功能更多
        Method method = signature.getMethod();//拓展:可获取切面的方法Method,反射里的知识.通过方法可以获取注解,参数,返回值类型等等信息
        Object target = joinPoint.getTarget();//拓展:可获取切面对应的类的对象实例
                                              //拓展:以上三行,获取到了Method以及对象实例,根据反射里的相关知识,此处可以做其他的一些拓展业务,自行脑补
        joinPoint.proceed(); // 此方法是核心!!! 代表原方法执行,必须要写,否则原方法不会执行
        System.out.println("环绕后置通知..................");
    }
}
补充小知识:

1.增强方法增加参数,可通过反射获取更多原方法信息,便于处理其他业务逻辑(如自定义注解相关)

如上Around的写法,可看到方法增加了一个参数ProceedingJoinPoint,但是此参数只能在@Around里使用,那其他类型的增强方法呢?可以使用JoinPoint,此接口不支持proceed()方法,即不可自执行原方法,但强转后也可获取反射对象Method以及原方法所在的实例,具体用处自行脑补

    @AfterReturning(value = "execution(* com.yyq.service.impl..*(..))")
    public void stringAfter(JoinPoint joinPoint) {
        System.out.println(joinPoint);
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();//拓展:代表切面方法,强转后功能更多
        Method method = signature.getMethod();//拓展:可获取切面的方法Method,反射里的知识.通过方法可以获取注解,参数,返回值类型等等信息
        Object target = joinPoint.getTarget();//拓展:可获取切面对应的类的对象实例
        //拓展:以上三行,获取到了Method以及对象实例,根据反射里的相关知识,此处可以做其他的一些拓展业务,自行脑补
        //此接口无proceed()方法.
        System.out.println("后置通知");
    }

2.相同切入点表达式抽取(简化书写)

同一个切面在每个注解里都写一遍比较混乱,不利于代码统一管理,此处有一个简化写法 @PointCut,示例如下:

@Component
@Aspect()
public class Log {
    @Pointcut(value = "execution(* com.yyq.service.impl.UserserviceImpl.say())")
    public void save(){

    }

    @Before(value = "save()")
    public void  strongBefore(){
        System.out.println("事前加强");
    }

    @After(value = "save()")
    public void  strongAfter(){
        System.out.println("事后加强");
    }
}

3.多个增强类增强同一个方法, 优先级写法

在增强类上增加@Order(),写上数字,值越小, 优先级越高

@Component
@Aspect()
@Order(1)
public class Log {
    @Pointcut(value = "execution(* com.yyq.service.impl.UserserviceImpl.say())")
    public void save(){

    }

    @Before(value = "save()")
    public void  strongBefore(){
        System.out.println("事前加强");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值