AOP

  • execution: 用于匹配方法执行的连接点。这是使用Spring AOP时要使用的主要切入点指示符。
  • within: 将匹配限制为某些类型内的连接点(使用Spring AOP时,在匹配类型内声明的方法的执行)。
  • this: 限制匹配到连接点(使用Spring AOP时方法的执行),其中bean引用(Spring AOP代理)是给定类型的实例。
  • target: 限制匹配到连接点(使用Spring AOP时方法的执行)的匹配,其中目标对象(正在代理的应用程序对象)是给定类型的实例。
  • args: 限制匹配到连接点(使用Spring AOP时方法的执行)的匹配,其中参数是给定类型的实例
  • @target: 限制匹配到连接点(使用Spring AOP时方法的执行)的匹配,其中执行对象的类具有给定类型的注释。
  • @args: 限制匹配的连接点(使用Spring AOP时方法的执行),其中传递的实际参数的运行时类型具有给定类型的注释。
  • @within: 限制匹配到具有给定注释的类型内的连接点(使用Spring AOP时,使用给定注释的类型中声明的方法的执行)。
  • @annotation: 将匹配点限制为连接点的主题(在Spring AOP中执行的方法)具有给定注释的连接点。

.Java

@Pointcut("execution(* transfer(..))") // the pointcut expression
private void anyOldTransfer() {} // the pointcut signature

.Java

@Pointcut("execution(public * \*(..))")
private void anyPublicOperation() {} // <1>

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

@Pointcut("anyPublicOperation() && inTrading()")
private void tradingOperation() {} // <3>

.Java

package com.xyz.someapp;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class SystemArchitecture {

	/**
	 * 如果以com.xyz.someapp.web包或该包下的任何子包中的类型定义该方法,则该连接点位于Web层中。
	 */
	@Pointcut("within(com.xyz.someapp.web..*)")
	public void inWebLayer() {}

	/**
	 * A join point is in the service layer if the method is defined
	 * in a type in the com.xyz.someapp.service package or any sub-package
	 * under that.
	 */
	@Pointcut("within(com.xyz.someapp.service..*)")
	public void inServiceLayer() {}

	/**
	 * A join point is in the data access layer if the method is defined
	 * in a type in the com.xyz.someapp.dao package or any sub-package
	 * under that.
	 */
	@Pointcut("within(com.xyz.someapp.dao..*)")
	public void inDataAccessLayer() {}

	/**
	 * A business service is the execution of any method defined on a service
	 * interface. This definition assumes that interfaces are placed in the
	 * "service" package, and that implementation types are in sub-packages.
	 *
	 * If you group service interfaces by functional area (for example,
	 * in packages com.xyz.someapp.abc.service and com.xyz.someapp.def.service) then
	 * the pointcut expression "execution(* com.xyz.someapp..service.*.*(..))"
	 * could be used instead.
	 *
	 * Alternatively, you can write the expression using the 'bean'
	 * PCD, like so "bean(*Service)". (This assumes that you have
	 * named your Spring service beans in a consistent fashion.)
	 */
	@Pointcut("execution(* com.xyz.someapp..service.*.*(..))")
	public void businessService() {}

	/**
	 * A data access operation is the execution of any method defined on a
	 * dao interface. This definition assumes that interfaces are placed in the
	 * "dao" package, and that implementation types are in sub-packages.
	 */
	@Pointcut("execution(* com.xyz.someapp.dao.*.*(..))")
	public void dataAccessOperation() {}

}

.Java

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class BeforeExample {

	@Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
	public void doAccessCheck() {
		// ...
	}

}

.Java

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterReturning;

@Aspect
public class AfterReturningExample {

	@AfterReturning(
		pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
		returning="retVal")
	public void doAccessCheck(Object retVal) {
		// ...
	}

}

.Java

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterThrowing;

@Aspect
public class AfterThrowingExample {

	@AfterThrowing(
		pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",
		throwing="ex")
	public void doRecoveryActions(DataAccessException ex) {
		// ...
	}

}

.Java

@Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation() && args(account,..)")
public void validateAccount(Account account) {
	// ...
}

.Java

@Pointcut("com.xyz.myapp.SystemArchitecture.dataAccessOperation() && args(account,..)")
private void accountDataAccessOperation(Account account) {}

@Before("accountDataAccessOperation(account)")
public void validateAccount(Account account) {
	// ...
}

.Java

@Before("com.xyz.lib.Pointcuts.anyPublicMethod() && @annotation(auditable)")
public void audit(Auditable auditable) {
	AuditCode code = auditable.value();
	// ...
}

Spring AOP可以处理类声明和方法参数中使用的泛型。假设您具有如下通用类型:
.Java

@Before("execution(* ..Sample+.sampleGenericMethod(*)) && args(param)")
public void beforeSampleMethod(MyType param) {
	// Advice implementation
}

.Java

@Aspect
public class UsageTracking {

	@DeclareParents(value="com.xzy.myapp.service.*+", defaultImpl=DefaultUsageTracked.class)
	public static UsageTracked mixin;

	@Before("com.xyz.myapp.SystemArchitecture.businessService() && this(usageTracked)")
	public void recordUsage(UsageTracked usageTracked) {
		usageTracked.incrementUseCount();
	}

}

.Java

@Aspect("perthis(com.xyz.myapp.SystemArchitecture.businessService())")
public class MyAspect {

	private int someState;

	@Before(com.xyz.myapp.SystemArchitecture.businessService())
	public void recordServiceUsage() {
		// ...
	}

}