Spring AOP(Aspect-Oriented Programming)实现原理主要基于代理模式。在Spring AOP中,会根据配置动态地在运行时创建代理对象,用来包裹目标对象。根据代理的类型,Spring AOP使用JDK动态代理或CGLIB来创建这些代理。
before
, after
, around
等类型的advice。在Spring中,AOP代理的创建过程主要由ProxyFactory
类处理:
让我们通过源码解析,看一下Spring是如何创建AOP代理的。
在AbstractAutoProxyCreator
类中有创建AOP代理的逻辑:
protected Object createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass(this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
} else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(getProxyClassLoader());
}
当代理对象的方法被调用时,方法拦截的逻辑是通过ReflectiveMethodInvocation
来处理的:
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
以上proceed()
方法确保了各种advice按照设定的顺序执行。对于@Around
、@Before
、@After
、@AfterReturning
、@AfterThrowing
等,都是通过相应的Advice
实现类来实现具体的拦截逻辑。
下面是一个使用Spring AOP的例子。我们定义一个简单的服务类和一个切面:
@Service
public class SimpleService {
public void performOperation() {
// 模拟方法执行
System.out.println("Performing operation...");
}
}
@Aspect
@Component
public class LoggingAspect {
@Before("execution(* SimpleService.performOperation(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Logging before operation: " + joinPoint.getSignature().getName());
}
}
在这个例子中,LoggingAspect
定义了一个@Before
通知,它会在SimpleService.performOperation()
方法执行前打印一条日志。
Spring AOP是基于代理模式的,它在运行时动态地创建代理对象,并根据定义的切面和通知来增加额外的行为。通过使用JDK动态代理或CGLIB,Spring能够将通知应用到目标对象的方法上。深入理解和使用Spring AOP能够让您在不改变现有业务逻辑代码的情况下,增加如日志、事务管理、安全控制等横切关注点。