gpt4 book ai didi

java - 如何检测/建议 Spring Data (JPA) 存储库?

转载 作者:IT老高 更新时间:2023-10-28 13:48:55 27 4
gpt4 key购买 nike

我未能为 spring 数据 jpa 存储库提供建议。目标是检测(围绕)特定存储库中的所有非 void 公共(public)方法,这些方法使用自定义注释(本示例中为 ResourceNotFound)进行注释,并在返回值为 null 时引发异常 或空集合。

@Repository 
@ResourceNotFound
@Transactional(readOnly = true)
public interface CityRepository extends JpaRepository<City, Long>, JpaSpecificationExecutor<City> { … }

以下建议是连接使用 @ResourceNotFound 注释的接口(interface)实现的所有公共(public)方法。

@Pointcut("within(com.digitalmisfits.spring.aop.annotation.ResourceNotFound *)")
public void beanAnnotatedWithResourceNotFound() {}

@Pointcut("execution(public * *(..))")
public void publicMethod() {}

@Around("beanAnnotatedWithResourceNotFound() && publicMethod()")
public Object publicMethodInsideAClassMarkedWithResourceNotFound(ProceedingJoinPoint pjp) throws Throwable {

System.out.println("publicMethodInsideAClassMarkedWithResourceNotFound " + pjp.getTarget().toString());;

Object retVal = pjp.proceed();

if(((MethodSignature) pjp.getSignature()).getReturnType() != Void.TYPE && isObjectEmpty(retVal))
throw new RuntimeException("isObjectEmpty == true");

return retVal;
}

publicMethodInsideAClassMarkedWithResourceNotFound(…) 方法在切入点指定为时起作用:

@Pointcut("execution(public * package.CityRepository+.*(..))")

但是,@ResourceNotFound 注释没有被拾取。这可能是因为存储库接口(interface)的底层类是(代理的)SimpleJpaRepository,它没有特定的注释。

有没有办法将@ResourceNotFound 传播到实现?

-- 更新--

更改了问题以反射(reflect)建议(围绕)仅应适用于具有自定义注释的存储库这一事实。

最佳答案

尽管 OP 严重依赖 AspectJ 解决方案,但目前的问题并不直接表明解决方案应仅限于 AspectJ。因此,我想提供一种非 AspectJ 方式来建议 Spring Data JPA Repository。它基于将自定义 Interceptor 添加到准系统 Spring AOP 代理拦截器链中。

首先,配置你的自定义RepositoryFactoryBean,例如

@Configuration
@EnableJpaRepositories(repositoryFactoryBeanClass = CustomRepositoryFactoryBean.class)
public class ConfigJpaRepositories {
}

接下来,实现CustomRepositoryFactoryBean,将自己的RepositoryProxyPostProcessor添加到JpaRepositoryFactory

class CustomRepositoryFactoryBean<R extends JpaRepository<T, I>, T , I extends Serializable> extends JpaRepositoryFactoryBean<R, T, I> {

protected RepositoryFactorySupport createRepositoryFactory(EntityManager em) {
RepositoryFactorySupport factory = super.createRepositoryFactory(em);
factory.addRepositoryProxyPostProcessor(new ResourceNotFoundProxyPostProcessor());
return factory;
}

}

您的 RepositoryProxyPostProcessor 实现应该将您的 MethodInterceptor 添加到特定存储库的 ProxyFactory(检查 RepositoryInformation):

class ResourceNotFoundProxyPostProcessor implements RepositoryProxyPostProcessor {

@Override
public void postProcess(ProxyFactory factory, RepositoryInformation repositoryInformation) {
if (repositoryInformation.getRepositoryInterface().equals(CityRepository.class))
factory.addAdvice(new ResourceNotFoundMethodInterceptor());
}

}

并且在您的 MethodInterceptor 中(顺便说一句,它是 org.aopalliance.aop.Advice 的子接口(interface),所以仍然是一个建议 :)) AspectJ @Around 建议:

class ResourceNotFoundMethodInterceptor implements MethodInterceptor {

@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Method method = invocation.getMethod();
ResourceNotFound resourceNotFound = method.getAnnotation(ResourceNotFound.class);
//...
Object result = invocation.proceed();
//...
return result;
}
}

关于java - 如何检测/建议 Spring Data (JPA) 存储库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26258158/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com