스프링 부트 1.1.8을 통해 스프링 4를 사용 중이며 일부 데이터를 캐시 할 클래스를 만들었습니다. 이 클래스는 제네릭을 사용하여 작동하지만 Spring에 문제가있어이 클래스를 다른 서비스의 bean으로 autowiring합니다.제네릭을 사용하는 스프링 4 빈 자동 와이어링
나는 다음과 같은 오류를 얻을 :
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [orm.repository.BaseRepository] is defined: expected single matching bean but found 2: dataTypeRepository,propertyNameRepository
클래스 질문에 다음과 같이
/**
* The purpose of this class is to get data from a cache backed by a database
* and if it does not exist to create it and insert into the database.
*/
@Service
public class CacheByName<TRepo extends BaseRepository, TItem extends BaseWithName> {
private final TRepo repo;
private final Class<TItem> itemClass;
private final Map<String, TItem> itemsCache; // TODO: change to better caching strategy
@Autowired
public CacheByName(TRepo repo, Class<TItem> itemClass) {
this.repo = repo;
this.itemClass = itemClass;
itemsCache = new HashMap();
}
public TItem getCreateItem(String name) {
TItem item = null;
if(itemsCache.containsKey(name)) {
item = itemsCache.get(name);
} else {
// try and load from db
item = (TItem) repo.findByName(name);
if(item == null) {
try {
item = itemClass.newInstance();
item.setName(name);
repo.saveAndFlush(item);
} catch (InstantiationException | IllegalAccessException ex) {
// TODO: log and handle better
return null;
}
}
itemsCache.put(name, item);
}
return item;
}
}
클래스 BaseRepository는 JpaRepository를 확장합니다. 다른 실제 저장소는 이것을 확장합니다.
@NoRepositoryBean
public interface BaseRepository<T extends Object, ID extends Serializable> extends JpaRepository<T, ID> {
public T findByName(String name);
}
클래스 BaseWithName은 이름 속성과 getters/setters를 정의하는 MappedSuperclass입니다. 다른 좀 더 구체적인 엔티티 클래스가이를 확장합니다.
CacheByName 클래스를 다음과 같은 다른 서비스에 삽입하려고합니다. 내가 생성자에서 제네릭과 실제 저장소 및 엔티티 클래스 정의하고 있습니다 :
@Service
public class DataImporter extends BaseImporter {
private static final Logger log = LoggerFactory.getLogger(PropertyImporter.class);
private final PropertyNameRepository propertyNameRepo;
private final CacheByName<DataTypeRepository, DataType> dataTypeCache;
@Autowired
public PropertyImporter(RestTemplate restTemplateD5,
CacheByName<DataTypeRepository, DataType> dataTypeCache) {
super(restTemplateD5);
this.dataTypeCache = dataTypeCache;
}
.
.
.
}
내 AppConfig.java의 모습을 다음
@Configuration
@ComponentScan
@EnableAutoConfiguration
public class AppConfig {
@Value("${username}")
private String username;
@Value("${password}")
private String password;
@Bean
public RestTemplate restTemplateD5() {
return RestTemplateFactory.createWithHttpBasicAuth(username, password);
}
}
내가 많은 정보를 찾을 수 없어 제네릭을 사용하는 빈을 만드는 방법. 내 AppConfig에 또 다른 @Bean 정의를 만들어야한다고 생각하는데, 제대로 된 것을 구현할 수 없었다.
가 왜 당신은 단순히 대신 Cacheable' 지원 @ 스프링을'using이됩니다
이 또한 캐스트가 더 이상 필요하지 않습니다해야합니까? 어노테이션과 빙고를 추가하여 캐싱을하면됩니다. –
예. 감사합니다. 미래에 사용할 계획이지만 제 질문은 캐싱 측면보다는 빈 인스턴스화에 관한 것입니다. – Hamish