Spring AOP 实践(五)基础篇下

本文详细介绍了Spring框架中AspectJ的切入点指示词及其应用,包括execution、within、this、target、args等,并通过实例展示了如何组合这些切点来实现更复杂的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring支持的AspectJ切入点指示词:

execution:匹配一个方法的执行,最常用的一个;

within:匹配在一个包或者类型中;

this:匹配一个这个类型的proxy;

target:匹配一个这个类型的目标对象--被代理的对象;

args:匹配一个方法,参数是这个类型;

组合切入点:

@Pointcut("execution(public * *(..))")
private void anyPublicOperation() {}

@Pointcut("within(com.xyz.someapp.trading..*)")
private void inTrading() {}

@Pointcut("anyPublicOperation() && inTrading()")
private void tradingOperation() {}

第一个切入点的定义用到了execution,指任何public的方法的执行;第二个切入点的定义用到了within,指在指定的包内;第三个切入点的定义则组合了两者,指在特定包中的任何public方法。

within(com.xyz.service.*)

within(com.xyz.service..*)
这两个within的区别在于,第二个包含了service这个包的子包,而第一个只是service这个包下面的所有类的意思。

this(com.xyz.service.AccountService)
指代任何继承了AccountService这个接口的proxy;

target(com.xyz.service.AccountService)
指代任何继承了AccountService这个接口的目标类;

args(java.io.Serializable)
任何以实现了Serializable接口的类为参数的切入点;

@target(org.springframework.transaction.annotation.Transactional)
目标对象有@Transactional的任何切入点;

@within(org.springframework.transaction.annotation.Transactional)
目标对象的声明类型中有@Transactional的任何切入点;

@annotation(org.springframework.transaction.annotation.Transactional)
执行的方法有@Transactional定义的任何切入点;

@args(com.xyz.security.Classified)
切入点只有一个参数,而且参数的类型有@Classified注解;

bean(tradeService)
任何定义在tradeService这个Bean中的切入点;

bean(*Service)
同上,只是bean的名字使用了通配符;

在切面中访问目标对象/目标方法的参数,返回值等:

    @AfterReturning(
        pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
        returning="retVal")
    public void doAccessCheck(Object retVal) {
        // ...
    }
    @AfterThrowing(
        pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
        throwing="ex")
    public void doRecoveryActions(DataAccessException ex) {
        // ...
    }
以上第一个例子访问目标方法的返回值,第二个方法访问发生的异常。

 @Around("com.xyz.myapp.SystemArchitecture.businessService()")
    public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
        // start stopwatch
        Object retVal = pjp.proceed();
        // stop stopwatch
        return retVal;
    }

使用ProceedingJoinPoint这个类可以获得目标方法的返回值,还可以获得目标对象:

Object target = pjp.getTarget();
或者目标方法的签名等:

String methodName = pjp.getSignature().getName();
org.aspectj.lang.JoinPoint类除了不能proceeding外其他功能和ProceedingJoinPoint相同;

@Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation() && args(account,..)")
public void validateAccount(Account account) {
    // ...
}
也可以这样访问目标对象的参数。
@Before("com.xyz.lib.Pointcuts.anyPublicMethod() && @annotation(auditable)")
public void audit(Auditable auditable) {
    AuditCode code = auditable.value();
    // ...
}
访问目标方法的注解。

具体实例可参见本系列的第二篇和第四篇。











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值