我正在尝试为实体类编写自定义JSF转换器。 我在项目中使用spring-data和spring-boot。
知道我有很多类是这样的:
@Component("myFirstConverter")
class MyFirstConverter implements Converter {
@Autowired
private MyFirstRepository myFirstRepository;
@Override
public Object getAsObject(FacesContext context, UIComponent component,
String value) {
return myFirstRepository.findOne(Long.parseLong(value));
}
//...
}
我创建了自定义类EntityConverter。它与CrudRepository一起使用。但是我不明白如何以编程方式创建bean数组并将其注入到每个bean对应的存储库中。
知道我尝试使用以下代码编写 @Configuration 类:
@Configuration
class MyConfig extends WebMvcConfigurerAdapter
@Bean
public static BeanFactoryPostProcessor registerConverters(ApplicationContext context) {
Map<String, Class<? extends CrudRepository>> converterBeans = new HashMap<>();
converterBeans.put("firstEntity", firstEntityRepository.class);
converterBeans.put("secondEntity", secondEntity.class);
return factory -> {
for (val entry : converterBeans.entrySet()) {
CrudRepository bean = context.getBean(entry.getValue()
factory.registerSingleton(entry.getKey()
.concat("Converter"), new EntityConverter(
entry.getKey(), bean));
}
};
但是它不起作用。应用程序初始化失败。
19:07:59.546 [WARN ] o.s.c.support.AbstractApplicationContext:551 -
Exception encountered during context initialization - cancelling
refresh attempt:
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'myFirstRepository': Cannot create inner bean
'(inner bean)#1fdfafd2' of type
[org.springframework.orm.jpa.SharedEntityManagerCreator] while setting
bean property 'entityManager'; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name '(inner bean)#1fdfafd2': Cannot resolve
reference to bean 'entityManagerFactory' while setting constructor
argument; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration$$EnhancerBySpringCGLIB$$fe46103]: No default constructor found; nested exception is java.lang.NoSuchMethodException: org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration$$EnhancerBySpringCGLIB$$fe46103.<init>()Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fumoRepository': Cannot create inner bean '(inner bean)#1fdfafd2' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property 'entityManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#1fdfafd2': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration$$EnhancerBySpringCGLIB$$fe46103]: No default constructor found; nested exception is java.lang.NoSuchMethodException:
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfigurati
on$$EnhancerBySpringCGLIB$$fe46103.<init>()
UPD:
允许WiPU解决该问题。我这样更改了registerConverters方法:
@Configuration
class MyConfig extends WebMvcConfigurerAdapter
@Bean
public static BeanFactoryPostProcessor
registerConverters(ApplicationContext context) {
Map<String, Class<? extends CrudRepository>> converterBeans = new HashMap<>();
converterBeans.put("firstEntity", firstEntityRepository.class);
converterBeans.put("secondEntity", secondEntity.class);
return factory -> {
BeanDefinitionRegistry beanFactory = (BeanDefinitionRegistry)
factory;
for (val entry : converterBeans.entrySet()) {
BeanDefinitionBuilder b =
BeanDefinitionBuilder.genericBeanDefinition(EntityConverter.class)
.addPropertyReference("repository", entry.getKey().concat("Repository"))
;
beanFactory.registerBeanDefinition(entry.getKey().concat("Converter"), b.getBeanDefinition());
factory.registerSingleton(entry.getKey()
.concat("Converter"), new EntityConverter(
entry.getKey(), bean));
}
};
答案 0 :(得分:1)
Spring无法根据显示的Exception实例化您的Repository Bean。
在装入所有bean定义但尚未实例化之后,将调用BeanFactoryPostProcessor
。您可以在此处找到详细信息:Link
在所有其他Bean已经正确实例化之后,您可以尝试在此过程中稍后注册Bean。您可以在此处找到一些详细信息:Link
此时,您所有的存储库都应该已经正确实例化,您只需添加其他EntityConverter
或者,如果您需要将EntityConverter
注入其他bean,则可以注册BeanDefinitons
。然后,当存储库已经创建时,Spring将实例化您的bean。 Link to JavaDoc
致谢, WiPu