title: Inject Spring Bean in Jackson VirtualBeanPropertyWriter
body: <p><strong>tldr;</strong> I want to add virtual fields while serializing the JPA entity into JSON using Jackson <code>@JsonAppend</code>. The value of the virtual fields must be determined via service managed by Spring. How do I inject my spring-managed service inside a Jackson class?</p>
  
  <p>Technologies: Spring Boot 1.5.10, Spring Data Rest, JPA 2.1, Jackson 2.8.10</p>
  
  <p><strong>Details:</strong></p>
  
  <p>I have a Spring Data managed JPA entity:</p>
  
  <pre class="lang-java prettyprint-override"><code>@Entity
  public class Stream {
     ...
  }
  </code></pre>
  
  <p>I created a Custom Jackson module with a Mixin to add <code>@JsonAppend</code> virtual field as below:</p>
  
  <pre class="lang-java prettyprint-override"><code>@Bean
  public Module customModule() {
      return new CustomModule();
  }
  
  @Component
  class CustomModule extends SimpleModule {
  
      CustomModule() {
          setMixInAnnotation(Stream.class, StreamMixin.class);
      }
  
      @JsonAppend(
              props = {
                      @JsonAppend.Prop(name = "canEdit", value = ABACInspector.class)
              }
      )
      abstract class StreamMixin {}
  
  }
  </code></pre>
  
  <p>The <code>ABACInspector</code> class extends Jackson's <code>VirtualBeanPropertyWriter</code> to determine the value of the virtual field <code>canEdit</code>. If this class does not use a Spring service (sets hard-coded value for example), it works fine and the field shows up in REST API JSON response. But autowiring a Spring bean doesn't work and the object remains <code>null</code>.</p>
  
  <pre class="lang-java prettyprint-override"><code>@Component
  class ABACInspector extends VirtualBeanPropertyWriter {
      @Autowired
      private PermissionEvaluator permissionEvaluator;
  
      public ABACInspector() {
      }
  
      public ABACInspector(BeanPropertyDefinition propDef, Annotations contextAnnotations, JavaType declaredType) {
          super(propDef, contextAnnotations, declaredType);
      }
  
      @Override
      protected Object value(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception {
          Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
          boolean permission = permissionEvaluator.hasPermission(authentication, bean, Action.STREAM_VIEW);
          System.out.println("evaluated permission is " + permission);
          return permission;
      }
  
      @Override
      public VirtualBeanPropertyWriter withConfig(MapperConfig&lt;?&gt; config, AnnotatedClass declaringClass, BeanPropertyDefinition propDef, JavaType type) {
          return new ABACInspector(propDef, null, type);
      }
  }
  </code></pre>
  
  <p>Below is the NPE error (because <code>permissionEvaluator</code> is never injected):</p>
  
  <pre><code>{"status":"INTERNAL_SERVER_ERROR","message":"Could not write JSON: 
  (was java.lang.NullPointerException); nested exception is com.fasterxml.jackson.databind.JsonMappingException: 
  (was java.lang.NullPointerException) (through reference chain: org.springframework.data.rest.webmvc.json.PersistentEntityJackson2Module$PersistentEntityResourceSerializer$1[\"content\"]-&gt;com.example.streammanagement.Stream[\"canView\"])"
  </code></pre>
  
  <p>I am aware of Spring Data Rest's <code>HalHandlerInstantiator</code> that contains the <code>AutowireCapableBeanFactory</code> but I am not sure how/if that can help here. Refer <a href="https://jira.spring.io/browse/DATAREST-840" rel="nofollow noreferrer">DATAREST-840</a></p>