当我运行 Cobertura 时,它会导致以下 Spring 自动装配错误:
原因:org.springframework.beans.factory.BeanCreationException:创建名为“userResource”的bean时出错:注入自动装配的依赖项失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:无法自动装配字段:私有 com.dnb.components.storage.service.UserService com.dnb.components.storage.rest.resource.UserResource.userService;嵌套异常是 java.lang.IllegalArgumentException: Can not set com.dnb.components.storage.service.UserService field com.dnb.components.storage.rest.resource.UserResource.userService to com.sun.proxy.$Proxy56 at org .springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287)
正如其他相关帖子中所建议的那样,我尝试通过更改“proxyTargetClass = true”来强制 Spring 使用 CGLIB,但这会导致不同的错误:
原因:org.springframework.beans.factory.BeanCreationException:创建名为“userResource”的bean时出错:注入自动装配的依赖项失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:无法自动装配字段:私有 com.dnb.components.storage.service.UserService com.dnb.components.storage.rest.resource.UserResource.userService;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“userService”的 bean 时出错:注入自动装配的依赖项失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:无法自动装配字段:com.dnb.components.storage.repository.UserRepository com.dnb.components.storage.service.UserService.repository;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“userRepository”的 bean 时出错:FactoryBean 对象的后处理失败;嵌套异常是 org.springframework.aop.framework.AopConfigException:无法生成类 [class com.sun.proxy.$Proxy54] 的 CGLIB 子类:此问题的常见原因包括使用最终类或不可见类;嵌套异常是 java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy54
这是 Repository 类的样子:
@Transactional
public interface UserRepository extends CrudRepository<User, Long> {
public User findByCrmId(String crmIdId);
}
这是使用 UserRepository 注入的服务:
@Service
@Transactional
public class UserService extends TraceablePersistenceService<User, UserRepository> {
@Autowired
UserRepository repository;
@Transactional
public Iterable<User> findAll() {
return repository.findAll();
}
public User findOne(Long id) {
return repository.findOne(id);
}
}
我们的配置在
@Configuration
@EnableTransactionManagement(proxyTargetClass=true)
@EnableJpaRepositories(basePackages = {"com.dnb.components.storage.repository"})
@Profile("inmemory")
public class InMemoryStandaloneStorageConfig extends BasicJpaStorageConfig {
....
(为简洁省略)
用户资源.java:
@Component
@Path(UserResource.uri)
public class UserResource extends AbstractResource {
public final static String uri = BASE_URI + "/users";
@Override
public String getURI() {
return BASE_URI + uri;
}
@Autowired
private UserService userService;
...
似乎 Spring Data JPA 生成的 Repository 类不能以任何一种方式代理,而不会搞砸自动装配。
有解决办法吗?使用 @Transactional 注释存储库方法甚至是一个好主意吗?注释是否应该仅在服务级别?