gpt4 book ai didi

java - Spring Data Repository 方面的建议不起作用

转载 作者:行者123 更新时间:2023-11-29 03:01:53 28 4
gpt4 key购买 nike

我正在尝试为存储库创建一些切入点和之前的建议,以便在 Spring Boot 中的 Spring Data 中启用对某些存储库的 entitymanager 过滤。我在项目中也有 web 和服务层,AspectLogging 对两者都有效。但是我不能对存储库做同样的事情。我已经苦苦挣扎了 2 天,我尝试了很多方法来修复它。我几乎阅读了所有关于此的文档、问题和线程(代理问题 CGlib 和 JDK 代理等)。我使用 jhipster 创建项目。

我无法使用 CrudRepository 部署除 @Pointcut 之外的应用程序。甚至它部署的 @Before 也不会被 Repository 中的方法调用调用。我想我有一个类似的问题,就像下面的问题一样。 proxy confusion

    Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.xxx.zzz.business.repository.ApplyRepository com.xxx.zzz.web.rest.applyResource.ApplyRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'applyRepository': Post-processing of FactoryBean's singleton object failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy173]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy173
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
... 61 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'applyRepository': Post-processing of FactoryBean's singleton object failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy173]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy173
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:116)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1523)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:314)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1120)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
... 63 more
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy173]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy173
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:212)
at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:109)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:447)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:333)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:293)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.postProcessObjectFromFactoryBean(AbstractAutowireCapableBeanFactory.java:1719)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:113)
... 70 more
Caused by: java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy173
at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:446)
at org.springframework.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33)
at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:317)
at org.springframework.aop.framework.ObjenesisCglibAopProxy.createProxyClassAndInstance(ObjenesisCglibAopProxy.java:56)
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:202)
... 77 more

有人知道它可能是什么吗?

类和配置如下所示。

存储库:

public interface ApplyRepository extends JpaRepository<Apply,Long>,QueryDslPredicateExecutor<Apply> {

public Page<Apply> findAll(Predicate predicate, Pageable p);
}
...
}

数据库配置:

@Configuration
@EnableJpaRepositories("com.xxx.zzz.business.repository")
@EnableJpaAuditing(auditorAwareRef = "springSecurityAuditorAware")
@EnableTransactionManagement//(proxyTargetClass = false)
public class DatabaseConfiguration {
....

AspectJ 配置:

@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
// @EnableLoadTimeWeaving(aspectjWeaving = ... )
public class LoggingAspectConfiguration {
...

系统架构:

@Aspect
public class SystemArchitecture {

/**
* A join point is in the web layer if the method is defined
* in a type in the com.xyz.someapp.web package or any sub-package
* under that.W
*/
@Pointcut("within(com.xxx.zzz.web.rest..*)")
public void inWebLayer() {
}

/**
* A join point is in the service layer if the method is defined
* in a type in the com.xyz.someapp.service package or any sub-package
* under that.
*/
@Pointcut("within(com.xxx.zzz.business.service..*)")
public void inServiceLayer() {
}

/**
* A join point is in the data access layer if the method is defined
* in a type in the com.xyz.someapp.dao package or any sub-package
* under that.
*/
@Pointcut("within(com.xxx.zzz.business.repository..*)")
public void inDataAccessLayer() {
}



/**
* All layers
*/
@Pointcut("inWebLayer() || inServiceLayer() || inDataAccessLayer()")
public void inALL(){
}



@Pointcut("within(org.springframework.data.repository.CrudRepository)")
//@Pointcut("execution(*org.springframework.data.repository.Repository+.* (..))")
//@Pointcut("execution(* com.xxx.zzz.business.repository+.*(..))")
//@Pointcut("execution(* org.springframework.data.jpa.repository.JpaRepository+.*(..))")
//@Pointcut("execution(* com.xxx.zzz.business.repository.ApplyRepository.*(..))")
public void inDATAExec(){}

}

过滤方面:

@Aspect
@Transactional
public class FilterAspect {

private final Logger log = LoggerFactory.getLogger(this.getClass());

@PersistenceContext
private EntityManager entitymanager;

@Before("com.xxx.zzz.aop.logging.SystemArchitecture.inDATAExec())") // "execution(* com.xxx.zzz.business.repository.InvoiceRepository.*(..))"
public void doAccessCheck() {
if (TransactionSynchronizationManager.isActualTransactionActive() && SecurityUtils.isAuthenticated()) {
Session session = entitymanager.unwrap(Session.class);
session.enableFilter("GLOBAL_FILTER").setParameter("customerId", SecurityUtils.getCurrentCustomerId());
}
}

编辑:我解决了问题。它以某种方式与错误的切入点和名称有关。我试图更改存储库中自定义注释的切入点。它不适用于方法或类级别。我在以下链接中阅读了有关此的问题。 advice 1 advice 2我为目标和注释苦苦挣扎了几个小时。但没有结果。 在 Spring Data Repositories 中添加自定义注解真的不可能吗?

注释:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
//@Inherited
public @interface CustomerRequired {
String value() default "customerrequired";
}

存储库:

public interface InvoiceRepository extends JpaRepository<Invoice,String>, QueryDslPredicateExecutor<Invoice> {

@CustomerRequired
public Page<Invoice> findAll(Predicate predicate, Pageable p);

...
}

切入点和建议:

@Pointcut(value = "@target(customerRequired)",argNames = "customerRequired")
public void targetCustomer(@SuppressWarnings("unused") CustomerRequired customerRequired) {/**/}


@Before(value = "com.xxx.zzz.aop.logging.SystemArchitecture.targetCustomer(customerRequired) && com.xxx.zzz.aop.logging.SystemArchitecture.inDataLayer()")
public void doAccessCheck(JoinPoint joinPoint, CustomerRequired customerRequired) {
if (TransactionSynchronizationManager.isActualTransactionActive() && SecurityUtils.isAuthenticated()) {
Session session = entitymanager.unwrap(Session.class);
session.enableFilter("GLOBAL_FILTER").setParameter("customerId", SecurityUtils.getCurrentCustomerId());
}
}

最佳答案

而不是使用

@Pointcut("within(org.springframework.data.repository.CrudRepository)")
public void inDATAExec(){}

像下面这样使用

@Pointcut("this(org.springframework.data.repository.Repository)")
public void inDATAExec(){}

它的作用是

any join point (method execution only in Spring AOP) where the 
proxy implements the Repository interface

你可以看看http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html

希望对您有所帮助!

关于java - Spring Data Repository 方面的建议不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34332046/

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