自动装配注释在自定义推土机转换器中不起作用
Autowired annotation doesn't work inside custom dozer converter
我正在使用下一个推土机自定义转换器
public class MyCustomDozerConverter extends DozerConverter<MyObject, String> {
@Autowired
private AppConfig appConfig;
public MyCustomDozerConverter() {
super(MyObject.class, String.class);
}
@Override
public String convertTo(MyObject source, String destination) {
String myProperty = appConfig.getWhatever();
// business logic
return destination;
}
@Override
public MyObject convertFrom(String source, MyObject destination) {
// business logic
return null;
}
}
我的问题是当它通过转换器内部的 convertTo 方法时,我总是得到具有空值的 appConfig 实例,这当然会导致空指针异常
注意:我的 spring 引导 class 上面有这些注释:
@SpringBootApplication
@EnableAutoConfiguration
@ComponentScan({"com.xxx"})
@EntityScan("com.xxx")
@EnableJpaRepositories("com.xxx")
尝试构造函数依赖注入
private AppConfig appConfig;
@Autowired
MyCustomerDozerConverter(AppConfig appConfig)
{
this.appConfig = appConfig;
}
我用下一个技巧解决了这个问题:
1- Using static with appConfig property.
2- instantiate it by spring so when dozer use default empty constructor it will find appConfig have
a value already (which assigned before to it by spring)
这是我为此使用的代码:
@Component //import org.springframework.stereotype.Component;
public class MyCustomDozerConverter extends DozerConverter<MyObject, String> {
private static AppConfig appConfig;
// dozer needs this constructor to create an instance of converter (so it's a mandatory constructor)
public MyCustomDozerConverter() {
super(MyObject.class, String.class);
}
@Autowired // Spring will pass appConfig to constructor
public MyCustomDozerConverter(AppConfig appConfig) {
this();
this.appConfig = appConfig;
}
@Override
public String convertTo(MyObject source, String destination) {
String myProperty = appConfig.getWhatever();
// business logic
return destination;
}
@Override
public MyObject convertFrom(String source, MyObject destination) {
// business logic
return null;
}
}
更新:另一个解决方案
另一个技巧是使用 Spring ApplicationContextAware 从 getBean 方法获取单例对象:
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class ApplicationContextHolder implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
public static ApplicationContext getContext() {
return context;
}
}
然后在 AppConfig 中创建静态方法 class 和 return 匹配所需类型的单个 bean 的实例:
import org.springframework.context.annotation.Configuration;
import com.tripbru.ms.experiences.ApplicationContextHolder;
@Configuration
public class AppConfig {
// Static method used to return an instatnce
public static AppConfig getInstance() {
return ApplicationContextHolder.getContext().getBean(AppConfig.class);
}
// Properties
}
然后通过 AppConfig.getInstance();
在推土机转换器内部直接调用它
public class MyCustomDozerConverter extends DozerConverter<MyObject, String> {
private static AppConfig appConfig;
public MyCustomDozerConverter() {
super(MyObject.class, String.class);
appConfig = AppConfig.getInstance(); // Here are we intializing it by calling the static method we created.
}
@Override
public String convertTo(MyObject source, String destination) {
String myProperty = appConfig.getWhatever();
// business logic
return destination;
}
@Override
public MyObject convertFrom(String source, MyObject destination) {
// business logic
return null;
}
}
您可以在 CustomConverter 中放置以下行,以便 Spring 自动装配它。
public class MyCustomDozerConverter extends DozerConverter<MyObject, String> {
@Autowired
private AppConfig appConfig;
public MyCustomDozerConverter() {
super(MyObject.class, String.class);
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
...
}
我正在使用下一个推土机自定义转换器
public class MyCustomDozerConverter extends DozerConverter<MyObject, String> {
@Autowired
private AppConfig appConfig;
public MyCustomDozerConverter() {
super(MyObject.class, String.class);
}
@Override
public String convertTo(MyObject source, String destination) {
String myProperty = appConfig.getWhatever();
// business logic
return destination;
}
@Override
public MyObject convertFrom(String source, MyObject destination) {
// business logic
return null;
}
}
我的问题是当它通过转换器内部的 convertTo 方法时,我总是得到具有空值的 appConfig 实例,这当然会导致空指针异常
注意:我的 spring 引导 class 上面有这些注释:
@SpringBootApplication
@EnableAutoConfiguration
@ComponentScan({"com.xxx"})
@EntityScan("com.xxx")
@EnableJpaRepositories("com.xxx")
尝试构造函数依赖注入
private AppConfig appConfig;
@Autowired
MyCustomerDozerConverter(AppConfig appConfig)
{
this.appConfig = appConfig;
}
我用下一个技巧解决了这个问题:
1- Using static with appConfig property.
2- instantiate it by spring so when dozer use default empty constructor it will find appConfig have a value already (which assigned before to it by spring)
这是我为此使用的代码:
@Component //import org.springframework.stereotype.Component;
public class MyCustomDozerConverter extends DozerConverter<MyObject, String> {
private static AppConfig appConfig;
// dozer needs this constructor to create an instance of converter (so it's a mandatory constructor)
public MyCustomDozerConverter() {
super(MyObject.class, String.class);
}
@Autowired // Spring will pass appConfig to constructor
public MyCustomDozerConverter(AppConfig appConfig) {
this();
this.appConfig = appConfig;
}
@Override
public String convertTo(MyObject source, String destination) {
String myProperty = appConfig.getWhatever();
// business logic
return destination;
}
@Override
public MyObject convertFrom(String source, MyObject destination) {
// business logic
return null;
}
}
更新:另一个解决方案
另一个技巧是使用 Spring ApplicationContextAware 从 getBean 方法获取单例对象:
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class ApplicationContextHolder implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
public static ApplicationContext getContext() {
return context;
}
}
然后在 AppConfig 中创建静态方法 class 和 return 匹配所需类型的单个 bean 的实例:
import org.springframework.context.annotation.Configuration;
import com.tripbru.ms.experiences.ApplicationContextHolder;
@Configuration
public class AppConfig {
// Static method used to return an instatnce
public static AppConfig getInstance() {
return ApplicationContextHolder.getContext().getBean(AppConfig.class);
}
// Properties
}
然后通过 AppConfig.getInstance();
在推土机转换器内部直接调用它public class MyCustomDozerConverter extends DozerConverter<MyObject, String> {
private static AppConfig appConfig;
public MyCustomDozerConverter() {
super(MyObject.class, String.class);
appConfig = AppConfig.getInstance(); // Here are we intializing it by calling the static method we created.
}
@Override
public String convertTo(MyObject source, String destination) {
String myProperty = appConfig.getWhatever();
// business logic
return destination;
}
@Override
public MyObject convertFrom(String source, MyObject destination) {
// business logic
return null;
}
}
您可以在 CustomConverter 中放置以下行,以便 Spring 自动装配它。
public class MyCustomDozerConverter extends DozerConverter<MyObject, String> {
@Autowired
private AppConfig appConfig;
public MyCustomDozerConverter() {
super(MyObject.class, String.class);
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
...
}