我一直在努力解决这个问题并浏览了很多文章,但无法找出解决方案。感谢您对以下问题的帮助。
我需要能够在服务类中自动装配EntityManager,但会引发异常。由于类型擦除,默认构造函数可能存在问题,因此我尝试使用带参数的构造函数来设置Type。如何自动装配用户类型的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)
答案 0 :(得分:3)
Spring 无法推断需要在User.class
的构造函数中注入EntityManager
以满足UserServiceImpl
中的depadenency。
如果您使用的是 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实现。
答案 1 :(得分:-1)
您的EntityManager类可能缺少 @Component 注释。
自动装配的构造函数需要一个未注入的类实体。
@Autowired(required=true)
public EntityManager(Class<T> entity) {
this.entity = entity;
}
尝试
@Autowired(required=true)
public EntityManager() {
}