更适合底层组件封装的的Aop实现

发布时间 2024-01-06 17:58:28作者: 这个冬天有点冷

直接上代码

@Slf4j
@Configuration(proxyBeanMethods = false)
public class AopConfig {
    
    @Bean
    public AopAnnotationPostProcessor aopAnnotationPostProcessor() {
        return new AopAnnotationPostProcessor(new AopMethodInterceptor(LogAop.class));
    }
    
    
    public static class AopAnnotationPostProcessor extends AbstractBeanFactoryAwareAdvisingPostProcessor {
        
        private final AopMethodInterceptor aopMethodInterceptor;
        
        public AopAnnotationPostProcessor(AopMethodInterceptor aopMethodInterceptor) {
            this.aopMethodInterceptor = aopMethodInterceptor;
        }
        
        @Override
        public void setBeanFactory(BeanFactory beanFactory) {
            super.setBeanFactory(beanFactory);
            this.advisor = new AopPointcutAdvisor(aopMethodInterceptor, aopMethodInterceptor.getAnnotationType());
        }
    }
    
    
    public static class AopMethodInterceptor implements MethodInterceptor, Ordered {
        
        private final Class<? extends Annotation> annotationType;
        
        public AopMethodInterceptor(Class<? extends Annotation> annotationType) {
            this.annotationType = annotationType;
        }
        
        @Override
        public Object invoke(final MethodInvocation invocation) throws Throwable {
            final Method targetMethod = invocation.getMethod();
            final Object[] arguments = invocation.getArguments();
            log.info("方法信息 :{}", targetMethod.getDeclaringClass());
            log.info("请求参数 :{}", arguments);
            //TODO 业务处理
            return invocation.proceed();
        }
        
        public Class<? extends Annotation> getAnnotationType() {
            return annotationType;
        }
        
        @Override
        public int getOrder() {
            return 0;
        }
        
    }
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    @Documented
    public @interface LogAop {
    
    }
    
    public static class AopPointcutAdvisor extends AbstractPointcutAdvisor {
        
        private final Advice advice;
        
        private final Pointcut pointcut;
        
        public AopPointcutAdvisor(Advice advice, Class<? extends Annotation> asyncAnnotationType) {
            this.advice = advice;
            this.pointcut = buildPointcut(Stream.of(asyncAnnotationType).collect(Collectors.toSet()));
        }
        
        @Override
        public Pointcut getPointcut() {
            return pointcut;
        }
        
        
        @Override
        public Advice getAdvice() {
            return advice;
        }
        
        private Pointcut buildPointcut(Set<Class<? extends Annotation>> asyncAnnotationTypes) {
            ComposablePointcut result = null;
            for (Class<? extends Annotation> asyncAnnotationType : asyncAnnotationTypes) {
                Pointcut cpc = new AnnotationMatchingPointcut(asyncAnnotationType, true);
                Pointcut mpc = AnnotationMatchingPointcut.forMethodAnnotation(asyncAnnotationType);
                if (result == null) {
                    result = new ComposablePointcut(cpc).union(mpc);
                } else {
                    result.union(cpc).union(mpc);
                }
            }
            return result;
        }
    }
}