spring使用AOP切换数据源的问题?

发布于 2022-09-12 22:42:38 字数 1715 浏览 14 评论 0

定义了一个自定义注解,可以作用在方法和类型,

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})  // 可以作用在类上、方法上
public @interface DS {
    String value() default "";
}

但是有一个问题,单独给类加上面的注解并没有触发AOP,而在方法上使用上面的注解可以触发AOP。这个是什么原因??

@Aspect
@Component
public class DynamicDataSourceAspect {
    @Before("@annotation(DS)")
    public void beforeSwitchDS(JoinPoint point){
        Class<?> target1 = point.getTarget().getClass();
 MethodSignature signature = (MethodSignature) point.getSignature();
 // 默认使用目标类型的注解,如果没有则使用其实现接口的注解
 for (Class<?> clazz : target1.getInterfaces()) {
            resolveDataSource(clazz, signature.getMethod());
 }
        resolveDataSource(target1, signature.getMethod());
 }
    @After("@annotation(DS)")
    public void afterSwitchDS(JoinPoint point){
        DataSourceContextHolder.clearDB();
 }
    /**
 * 提取目标对象方法注解和类型注解中的数据源标识 * * @param clazz
 * @param method
 */
 private void resolveDataSource(Class<?> clazz, Method method) {
        try {
            Class<?>[] types = method.getParameterTypes();
 // 默认使用类型注解-也就是使用定义类上面的注解
 if (clazz.isAnnotationPresent(DS.class)) {
                DS source = clazz.getAnnotation(DS.class);
 System.out.println("类上的注解"+source.value());
 DataSourceContextHolder.setDB(source.value());
 }
            // 方法注解可以覆盖类型注解-也就是使用方法上的注解去替换类上面的注解
 Method m = clazz.getMethod(method.getName(), types);
 if (m != null && m.isAnnotationPresent(DS.class)) {
                DS source = m.getAnnotation(DS.class);
 System.out.println("方法上的注解"+source.value());
 DataSourceContextHolder.setDB(source.value());
 }
        } catch (Exception e) {
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烟酉 2022-09-19 22:42:38

上次debug看了下这个鬼东西,当你用@annotation去做拦截的时候,查找注解,他直接从方法上面查找的,所以你写直接到类上没啥用
入口代码:org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary,这个方法,当你类和方法上写注解,结果是不同的
image.png

最关键匹配的地方:
org.aspectj.weaver.patterns.ExactAnnotationTypePattern.matches(annotated,parameterAnnotations)
image.png
annotated的实现类此时是ReflectionBasedResolvedMemberImpl,
image.png

宛菡 2022-09-19 22:42:38

https://gitee.com/baomidou/dy...
多数据源解决方案。

你的问题,可以用现成的切点。
https://gitee.com/baomidou/dy...

private Pointcut buildPointcut() {

    Pointcut cpc = new AnnotationMatchingPointcut(DS.class, true);

    Pointcut mpc = new AnnotationMethodPoint(DS.class);

    return new ComposablePointcut(cpc).union(mpc);

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文