简体   繁体   English

自动装配注释在自定义推土机转换器中不起作用

[英]Autowired annotation doesn't work inside custom dozer converter

I am using next dozer custom 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;
    }
}

My problem is when it goes through convertTo method inside the converter, I always got appConfig instance with null value which of course cause a null pointer exception 我的问题是,当它通过转换器内部的convertTo方法时,我总是得到带有null值的appConfig实例,这当然会导致null指针异常

Note: my spring boot class have these annotations above: 注意:我的spring boot类上面有这些注释:

@SpringBootApplication
@EnableAutoConfiguration
@ComponentScan({"com.xxx"})
@EntityScan("com.xxx")
@EnableJpaRepositories("com.xxx")

I solved this by next trick: 我通过下一个技巧解决了这个问题:

1- Using static with appConfig property. 1-使用带有appConfig属性的static。

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) 2-通过spring实例化,因此当推土机使用默认的空构造函数时,它将发现appConfig已经具有一个值(该值由spring分配给它)

And here are the code i used for this: 这是我用于此的代码:

@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;
    }
}

UPDATE: Another solution 更新:另一个解决方案

Another trick is using Spring ApplicationContextAware to get a singleton object from getBean method: 另一个技巧是使用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;
    }
}

Then create a static method inside AppConfig class and return an instance of the single bean matching the required type: 然后在AppConfig类内创建一个静态方法,并返回与所需类型匹配的单个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
}

Then calling it direct inside the dozer converter by AppConfig.getInstance(); 然后通过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;
    }
}

Try constructor dependency injection 尝试构造函数依赖注入

private AppConfig appConfig;
@Autowired
MyCustomerDozerConverter(AppConfig appConfig)
{
    this.appConfig = appConfig;
}

You can put following line in the CustomConverter so that Spring will autowire it. 您可以将以下行放入CustomConverter中,以便Spring对其进行自动布线。

public class MyCustomDozerConverter extends DozerConverter<MyObject, String> {

@Autowired
private AppConfig appConfig;

public MyCustomDozerConverter() {
    super(MyObject.class, String.class);
    SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM