[英]Spring autowiring issues on paramaterized class
我已經為這個問題苦苦掙扎了一段時間,並且瀏覽了很多文章,但是找不到解決方案。 感謝您對以下問題的幫助。
我需要能夠在服務類中自動裝配EntityManager,但是會引發異常。 默認構造函數可能由於類型擦除而存在問題,因此我嘗試使用帶有參數的構造函數來設置Type。 如何自動連接User類型的EntityManager?
public interface IEntityManager<T extends IDomain<ID>, ID extends Serializable> {
T findById(ID id, boolean lock);
T save(T entity);
void delete(T entity);
}
public class EntityManager<T extends IDomain<ID>, ID extends Serializable>
implements IEntityManager<T, ID> {
private Class<T> entity;
@Autowired(required=true)
private SessionFactory sessionFactory;
/*
@SuppressWarnings("unchecked")
public EntityManager() {
this.entity = (Class<T>) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];
} */
@Autowired(required=true)
public EntityManager(Class<T> entity) {
this.entity = entity;
}
}
@Service("UserService")
@Transactional
public class UserServiceImpl implements IUserService {
@Autowired
EntityManager<User, Integer> entityManager;
}
這是例外:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'UserService': Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.test.dummy.persistence.manager.EntityManager com.test.dummy.service.UserServiceImpl.entityManager; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.test.dummy.persistence.manager.EntityManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
Spring 無法推斷出需要在EntityManager
的構造函數中注入User.class
來滿足UserServiceImpl
的依賴性。
如果使用Spring 4 ,則可以定義EntityManager<User, Integer>
類型的Bean:
@Configuration
public class Config {
@Bean
public EntityManager<User, Integer> userEntityManager() {
new EntityManager(User.class);
}
}
編輯:或定義一個BeanDefinitionRegistryPostProcessor ,它將檢查需要EntityManager作為依賴項的bean,標識所需的類型,構造所需類型的新EntityManager bean並將其添加到bean注冊表中。
@Component
public class MyEntityManagerBeanDefinitionRegistryPostProcessor implements
BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanFactory(final ConfigurableListableBeanFactory beanFactory)
throws BeansException {
for (String beanName : beanFactory.getBeanDefinitionNames()) {
final BeanDefinition beanDefinition = getOriginatingBeanDefinition(
beanFactory.getBeanDefinition(beanName));
final Class<?> beanClass = getClass(beanDefinition.getBeanClassName());
if (beanClass != null) {
ReflectionUtils.doWithFields(beanClass, new ReflectionUtils.FieldCallback() {
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
if (field.isAnnotationPresent(Autowired.class) || field.isAnnotationPresent(
Inject.class)) {
if (field.getGenericType() instanceof ParameterizedType) {
final ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType();
final Class<?> rawType = (Class) parameterizedType.getRawType();
if (rawType.equals(EntityManager.class)) {
final Class<?> typeArgument = (Class<?>) parameterizedType.getActualTypeArguments()[0];
beanFactory.registerSingleton(field.getName(), new EntityManager(typeArgument));
}
}
}
}
});
}
}
}
private Class<?> getClass(String className) throws BeansException {
if (className != null) {
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
throw new BeanInitializationException("beanClass not found", e);
}
}
return null;
}
private BeanDefinition getOriginatingBeanDefinition(BeanDefinition beanDefinition) {
while(beanDefinition.getOriginatingBeanDefinition() != null) {
beanDefinition = beanDefinition.getOriginatingBeanDefinition();
}
return beanDefinition;
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { }
}
最后,看起來您實際需要的是使用Spring Data Jpa ,從本質上講,您可以通過定義如下接口來定義參數化DAO:
package com.myapp.repository;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {}
您啟用它:
@Configuration
@EnableJpaRepositories(basePackages = "com.myapp.repository")
public class Config {
}
然后,您注入UserRepository
:
@Autowired
private UserRepository userRepository;
Spring將注入一個基本的DAO實現。
您可能在EntityManager類上缺少@Component批注。
自動裝配的構造函數需要一個未注入的類實體。
@Autowired(required=true)
public EntityManager(Class<T> entity) {
this.entity = entity;
}
嘗試
@Autowired(required=true)
public EntityManager() {
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.