Я пытаюсь преобразовать 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 ... Как внедрить услугу?
Могу ли я получить службу из контекста и внедрить ее в конструктор по умолчанию?




Это невозможно. Только объекты, экземпляры которых были созданы с помощью Spring, могут использовать @Autowired.
Это просто: когда вы аннотируете объект с помощью @Service, spring попытается разрешить все его зависимости с помощью интроспекции.
С Джексоном (или если вы пытаетесь создать экземпляр объекта самостоятельно) вы полностью выходите за рамки Spring.
И я должен был знать, что то, что вы пытаетесь сделать (даже если бы это было возможно), не является хорошей практикой. Не следует смешивать объекты данных с бизнес-обработкой.
Я понимаю это, но могу ли я ввести его, например, в конструктор по умолчанию? Не обязательно использовать аннотацию с автоматическим подключением для вставки bean-компонента.
@xyz Невозможно, поскольку Jackson потребности пустой конструктор.
Вы всегда можете добавить сеттер для своего сервиса. Но зачем вам это делать? Вы не должны получать такие объекты извне вашего приложения.
например, если служба проверяет dto
Если служба проверяет только dto, вы можете использовать чистые функции вместо использования службы (или использовать библиотеки проверки, уже интегрированные в spring и jax-rs, например hibernate-validator).
Как было сказано ранее, внедрение сервисов возможно только с такими фреймворками, как Spring.
Если вы используете Spring, аннотируйте свой класс службы с помощью @Service, а затем, в отличие от использования @Autowired, объявите свою службу закрытым финалом и введите его с помощью конструктора (IMO, я считаю, что это работает лучше).
Если вы не используете Spring, вам нужно создать новый экземпляр службы, а затем вызвать этот экземпляр - если, конечно, это не статический ...
Джексону нужны пустые конструкторы.
Если вы выполняли инициализацию объекта SimpleClass самостоятельно, вы можете заставить его работать, автоматически подключив частичный экземпляр с помощью AutowireCapableBeanFactory, в этом случае @Autowrire службы будет работать, поскольку Spring также управляет частичным экземпляром объекта SomeClass.
Тем не менее, это не выход. Объекты данных должны быть изолированы от бизнес-логики.
Вернемся к вашему случаю, вы не можете автоматически подключать даже так, как я говорил, потому что Джексон является поставщиком экземпляра, а Джексон требует - наличие пустого конструктора.
Поскольку вам нужно какое-то автоматическое подключение в вашем компоненте 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 bean-компонента.
@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();
}
Джексон - это среда де / сериализации JSON / XML, а не CDI.