Ошибка BeanCreationException при обращении к классу конфигурации внутри класса обслуживания - PullRequest
1 голос
/ 10 апреля 2020

Я пытаюсь @Autowire @Configuration класс внутри @Service класса. в основном мой класс @Configuration содержит сопоставление с моим пользовательским файлом .properties. Когда я пытаюсь автоматически связать мой класс конфигурации с классом обслуживания, возникает BeanCreationException. Я не уверен, что случилось. Просто следовал руководству по созданию классов недвижимости с весны. Должно быть что-то, что я пропустил.

Кроме того, когда я пытаюсь автоматически связать @Configuration класс с другим @Configuration классом, он работает гладко

В настоящее время я знаю, что prop всегда пусто, потому что когда я удаляю вызов prop.getUploadFileLocation(), все будет хорошо. Должно быть что-то не так во время автоматической проводки.

Вот мой класс обслуживания

    @Service
    public class ImageService {

        public static Logger logger = Logger.getLogger(ImageService.class.getName());

        @Autowired
        MyProperties prop;

        private final String FILE_UPLOAD_LOCATION = prop.getUploadFileLocation() +"uploads/images/";

        public void upload(String base64ImageFIle) throws IOException {
            logger.info(FILE_UPLOAD_LOCATION);
        }
    }

Вот мой класс конфигурации

    @Data
    @Configuration
    @ConfigurationProperties (prefix = "my")
    public class MyProperties {

        private String resourceLocation;

        private String resourceUrl;

        public String getUploadFileLocation() {
            return getResourceLocation().replace("file:///", "");
        }

        public String getBaseResourceUrl() {
            return getResourceUrl().replace("**", "");
        }
    }

А вот где я могу успешно использовать MyProperties

    @Configuration
    public class StaticResourceConfiguration implements WebMvcConfigurer {

        @Autowired
        MyProperties prop;

        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler(prop.getResourceUrl())
                    .addResourceLocations(prop.getResourceLocation());
        }
    }

Ответы [ 2 ]

3 голосов
/ 10 апреля 2020

Проблема заключается в том, что вы пытаетесь использовать автоматическое поле для установки значения во встроенном поле.

Это означает, что

private final String FILE_UPLOAD_LOCATION = prop.getUploadFileLocation() +"uploads/images/";

выполняется до того, как prop будет autowired, что означает, что он всегда будет нулевым

Чтобы уменьшить это, можно использовать вместо этого инъекцию конструктора.

@Service
public class ImageService {

    //Fine since you are using static method
    public static Logger logger = Logger.getLogger(ImageService.class.getName());

    //Not needed if you are only using it to set FILE_UPLOAD_LOCATION
    //Allows field to be final
    private final MyProperties prop;

    //Still final
    private final String FILE_UPLOAD_LOCATION;

    //No need for @Autowired since implicit on component constructors
    ImageService(MyProperties prop){

        //Again not needed if you aren't going to use anywhere else in the class
        this.prop = prop;

        FILE_UPLOAD_LOCATION = prop.getUploadFileLocation() +"uploads/images/";
    }

    public void upload(String base64ImageFIle) throws IOException {
        logger.info(FILE_UPLOAD_LOCATION);
    }
}

См. этот вопрос , почему конструктор предпочтителен в общем @autowired

0 голосов
/ 10 апреля 2020

Если вам нужно создать компонент MyProperties до компонента StaticResourceConfiguration, вы можете указать @ConditionalOnBean(MyProperties.class) следующим образом. Spring проверит наличие MyProperties перед обработкой StaticResourceConfiguration.

@Configuration
@ConditionalOnBean(MyProperties.class)
public class StaticResourceConfiguration implements WebMvcConfigurer {
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...