Gleeb
Gleeb

Reputation: 11299

How to @autowire some bean into JsonSerializer?

I am using lazy loading with hibernate in my web app.

I would like to load some objects from the database at the parsing stage of the server response

@Component
public class DesignSerializer extends JsonSerializer<Design> {
@Autowired
IDesignService designService; <-- is null

}

Which is totally understandable because DesignSerializer is being instantiated with the "new" operator for each object.

I am sure there is a way to inject my bean into that serializer when ever it is created, I just don't know how.

Can you guys help me or point me in the right direction.

Upvotes: 32

Views: 16788

Answers (4)

Gleeb
Gleeb

Reputation: 11299

I Solved the problem by creating a static field in a different bean and then @Autowire its setter method.

@Service("ToolBox")
@Transactional
public class ToolBox 
{
    static Logger logger = Logger.getLogger(ToolBox.class);
        
    private static IService service;
    
    @Autowired
    public void setService(IService service)
    {
        ToolBox.service = service;
    }
    
    public static IService getService()
    {
        return ToolBox.service;
    }
}

like shown in this thread: Can you use @Autowired with static fields?

Upvotes: 4

Jaims
Jaims

Reputation: 1575

If you're using Spring Boot, @JsonComponent will do the autowiring for you.

@JsonComponent
public class DesignSerializer extends JsonSerializer<Design> {
    @Autowired
    private DesignService designService;
}

Testing this serializer can then be done while autoconfiguring json support.

@AutoConfigureJson
@SpringBootTest
class DesignSerializerTest {

    @Autowired
    private ObjectMapper objectMapper;
    
    @Test
    void testDesignSerializer() {
        objectMapper.writer().writeValueAsString(new Design());
    }
}    

Upvotes: 3

veiset
veiset

Reputation: 2003

We had the same problem with JsonSerializer and Spring autowiring. The solution that worked for us was to make two constructors. One for Spring which sets the dependency as a static field, and another one that is used by the Jackson initialisation.

This works because the Spring dependency injection (autowiring) happens before Jackson initialises the serializer.

@Component
public class MyCustomSerializer extends JsonSerializer<String> {

    private static IDesignService designService;

    // Required by Jackson annotation to instantiate the serializer
    public MyCustomSerializer() { }

    @Autowired
    public MyCustomSerializer(IDesignService designService) {
        this.designService = designService;
    }

    @Override
    public void serialize(String m, JsonGenerator gen, SerializerProvider s) {
        gen.writeObject(MyCustomSerializer.designService.method(..));
    }
}

Upvotes: 23

Peter Jurkovic
Peter Jurkovic

Reputation: 2896

Solution is SpringBeanAutowiringSupport if you are using Spring Framework 2.5+.

public class DesignSerializer extends JsonSerializer<Design> {

    @Autowired
        IDesignService designService;
    }

    public DesignSerializer(){
        SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);    
    }

...

}

I Hope that help you

Upvotes: 34

Related Questions