Spring完成AOP代理有两种途径,一种依赖
AbstractAutoProxyCreator
来完成自动代理(例如事务就是依赖其子类完成代理)。另一种是依赖AbstractAdvisingBeanPostProcessor
来完成代理(例如@Async就是依赖其子类完成代理)。
使用AbstractAutoProxyCreator
完成AOP代理,只需要将Advisor
注册到Spring容器中。而AbstractAdvisingBeanPostProcessor
需要使用其子类来完成AOP代理。
1. AbstractAdvisingBeanPostProcessor子类
image.png
Spring使用模板方法模式,只是将个性化的功能留给子类来实现,那么我们先点击MethodValidationPostProcessor
类,看下它实现了父类什么方法。
image.png
那么MethodValidationPostProcessor
做了什么?便完成了对方法校验的AOP代理???
public class MethodValidationPostProcessor extends AbstractBeanFactoryAwareAdvisingPostProcessor
implements InitializingBean {
//在初始化时,创建了一个Advisor并赋予给父类
//(AbstractAdvisingBeanProcessor)的advisor属性。
@Override
public void afterPropertiesSet() {
Pointcut pointcut = new AnnotationMatchingPointcut(this.validatedAnnotationType, true);
this.advisor = new DefaultPointcutAdvisor(pointcut, createMethodValidationAdvice(this.validator));
}
protected Advice createMethodValidationAdvice(@Nullable Validator validator) {
return (validator != null ? new MethodValidationInterceptor(validator) : new MethodValidationInterceptor());
}
}
只是在后置处理器定义了一个Advisor,并将其赋予给父类的属性,Spring便可以使用该Advisor对Bean进行代理。
没错,就是这么简单!!!
3. 注解版日志打印实战
@Target({ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyLogAnno {
Class<?>[] value() default {};
}
定义后置后置处理器(声明advisor),在项目启动的时会对类进行AOP代理。
@Slf4j
@Component
public class MyLogAnnoBeanPostProcessor extends AbstractBeanFactoryAwareAdvisingPostProcessor
implements InitializingBean {
private Class<? extends Annotation> myLogAnnoType = MyLogAnno.class;
@Override
public void afterPropertiesSet() throws Exception {
//对带有myLogAnno注解的方法进行拦截
Pointcut pointcut =AnnotationMatchingPointcut.forMethodAnnotation(myLogAnnoType);
this.advisor = new DefaultPointcutAdvisor(pointcut,
(MethodBeforeAdvice) (method, args, target) -> {
//打印日志
log.info("调用方法:[{}]", method);
log.info("方法参数:[{}]", JSON.toJSONString(args));
log.info("target类:[{}]", target);
});
}
}