Как преобразовать объект с помощью ObjectMapper и вставить в него зависимости - PullRequest
0 голосов
/ 08 июня 2018

Я пытаюсь преобразовать Object в конкретный класс, используя jackson ObjectMapper и внедрить зависимости после того, как я его преобразовал. Вот пример:

public class SimpleClass{
    private String parameter;
    @JsonIgnore
    private SomeService service;

    /** getters and setters **/
    public void doSomethingFromService(){
        //call some methods from the service
    }
}

После попытки десериализации объекта (значение - карта, содержащаяпараметры):

ObjectMapper om = new ObjectMapper();
om.convertValue(value,SimpleClass.class).doSomethingFromService();

-> привести к исключению NullPointerException ... Как внедрить службу?

Можно ли получить службу из контекста и внедрить ее по умолчанию в конструкторе?

Ответы [ 4 ]

0 голосов
/ 09 июня 2018

Поскольку вам нужна какая-то автоматическая разводка в вашем бине SimpleClass, вам нужно аннотировать его свойство SomeService service с помощью @Autowired.

public class SimpleClass {

    private String parameter;

    @JsonIgnore
    @Autowired
    private SomeService service;

    // getter and setter for parameter (omitted here for brevity)

    public void doSomethingFromService(){
        //call some methods from the service
    }
}

Как уже говорили другие, ObjectMapperне делает никаких инъекций зависимости.Но вы можете комбинировать @Autowired -игнорирование ObjectMapper с некоторым автоматическим подключением, запускаемым вручную.

Для этого вам понадобится AutowireCapableBeanFactory, который вы получите путем обычного внедрения зависимостей Spring с@Autowired.Затем вы используете его метод autowireBean(Object) для добавления свойств @Autowired компонента.

@Autowired
private  AutowireCapableBeanFactory autowireCapableBeanFactory;

public void doSomething(Map<String, Object> value) throws Exception {
    ObjectMapper om = new ObjectMapper();
    SimpleClass bean = om.convertValue(value, SimpleClass.class);
    autowireCapableBeanFactory.autowireBean(bean);
    bean.doSomethingFromService();
}
0 голосов
/ 08 июня 2018

Внедрение сервисов возможно только с такой средой, как Spring, как было сказано ранее.

Если вы используете Spring, аннотируйте свой класс обслуживания с помощью @Service, а затем, в отличие от @Autowired, объявите свой сервис закрытым.final и внедрить его с помощью конструктора (IMO, я считаю, это работает лучше).

Если вы не используете Spring, вам нужно будет обновить экземпляр службы, а затем вызвать этот экземпляр - если толькоконечно это статично ...

0 голосов
/ 08 июня 2018

Если вы выполняли инициализацию объекта SimpleClass самостоятельно, вы можете заставить его работать, автоматически подключая экземпляр paritcular с AutowireCapableBeanFactory , в этом случае @Autowrire службы будет работать, поскольку Spring управляеттакже частичный экземпляр объекта SomeClass.

Тем не менее, это не тот путь.Объекты данных должны быть изолированы от бизнес-логики.

Возвращаясь к вашему случаю, вы не можете выполнить автоматическое подключение даже так, как я описал, потому что Джексон является поставщиком экземпляра, а Джексон требует наличия пустого конструктора.

0 голосов
/ 08 июня 2018

Это невозможно.@ Autowired могут использовать только объекты, для которых был создан экземпляр Spring.

Все просто: когда вы аннотируете объект с помощью @Service, Spring попытается разрешить все его зависимости с помощью самоанализа.

С Джексоном(или если вы пытаетесь создать объект самостоятельно), вы совершенно вне рамок весны.

И я должен был сказать, что вы пытаетесь сделать (даже если это было возможно), это не хорошопрактика.Вы не должны смешивать ваши объекты данных с бизнес-обработкой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...