Cobertura を実行すると、次の Spring 自動配線エラーが発生します。
原因: org.springframework.beans.factory.BeanCreationException: 'userResource' という名前の Bean の作成中にエラーが発生しました: 自動配線された依存関係の注入に失敗しました。ネストされた例外は org.springframework.beans.factory.BeanCreationException: Could not autowire フィールドです: private com.dnb.components.storage.service.UserService com.dnb.components.storage.rest.resource.UserResource.userService; ネストされた例外は java.lang.IllegalArgumentException です: 組織で com.dnb.components.storage.service.UserService フィールド com.dnb.components.storage.rest.resource.UserResource.userService を com.sun.proxy.$Proxy56 に設定できません.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: Could not autowire フィールドです: private 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: Could not autowire フィールドです: 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: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy54]: この問題の一般的な原因には、最終クラスまたは非表示クラスの使用が含まれます。ネストされた例外は java.lang.IllegalArgumentException です: 最終クラス クラス com.sun.proxy.$Proxy54 をサブクラス化できません
リポジトリ クラスは次のようになります。
@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 {
....
(簡潔にするために省略)
UserResource.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 でリポジトリ メソッドに注釈を付けるのは良い考えですか? 注釈はサービス レベルのみにする必要がありますか?