0

I have this non-managed class that I want to inject spring beans (that I don't known a-priory what they are). How can I do that?

For example, let's say I have the following class:

public class NonManagedClass extends APIClass {

  @Resource
  private Service1 service;

  @Resource
  private Service2 service2;

  // here i can declare many different dependencies

  @Resource
  private ServiceN serviceN;

  @Override
  public void executeBusinessStuffs() {
    // business logics
  }

}

I need in someway to let spring inject these dependencies in my class. I have access to these objects after created, so it's easy to me call any method that can accomplish this functionality. For example:

@Service
public void SomeAPIService {

  @Resource
  private BeanInjector beanInjector; // I'm looking for some funcionality of spring like this

  public void someProcessingFunction(Class<? extends APIClass> clazz) throws Exception {
    APIClass instance = clazz.getConstructor().newInstance();
    beanInjector.injectBeans(instance);
    instance.executeBusinessStuffs();
  }

}

Does Spring have such functionality to inject beans based on fields annotation for a non-managed class?

João Pedro Schmitt
  • 1,046
  • 1
  • 11
  • 25
  • I dont think spring will provide this feature for any reason.. it will make the overall framework a big mess. However, you can use reflection to make this possible – Anand Vaidya Aug 19 '20 at 14:03
  • If you still insist to make this work, refer this thread - https://stackoverflow.com/questions/32716952/set-private-field-value-with-reflection – Anand Vaidya Aug 19 '20 at 14:04
  • 1
    Inject the `ApplicationContext` and use `getAutowireCapableBeanFactory().autowireBean(instance);`. Or let Spring do it all and use `getAutowireCapableBeanFactory().createBean(clazz);`. – M. Deinum Aug 19 '20 at 14:20

1 Answers1

3

Replace BeanInjector with ApplicationContext and you are almost there. From there you can get the AutowireCapableBeanFactory which provides some handy methods like createBean and autowireBean.

@Service
public void SomeAPIService {

  @Resource
  private ApplicationContext ctx;

  public void someProcessingFunction(Class<? extends APIClass> clazz) throws Exception {
    APIClass instance = ctx.createBean(clazz);
    instance.executeBusinessStuffs();
  }
}

or if you really like to construct stuff yourself instead of using the container:

@Service
public void SomeAPIService {

  @Resource
  private ApplicationContext ctx;

  public void someProcessingFunction(Class<? extends APIClass> clazz) throws Exception {
    APIClass instance = clazz.getConstructor().newInstance();
    ctx.getAutowireCapableBeanFactory().autowireBean(instance);
    instance.executeBusinessStuffs();
  }
}
João Pedro Schmitt
  • 1,046
  • 1
  • 11
  • 25
M. Deinum
  • 115,695
  • 22
  • 220
  • 224
  • Hm.. good point. Do you know if using this `autowireBean` create any records in spring's data-structures? I don't wanna to create information there, I just want to wire the dependencies in this loose instance. I'm asking this because I've seen this another methods there, like `autowireBeanProperties` from `AutowireCapableBeanFactory`. – João Pedro Schmitt Aug 19 '20 at 17:08
  • I have no idea what you mean by **reate any records in spring's data-structures**? What has Spring Data and records to do with autowiring? – M. Deinum Aug 19 '20 at 17:33
  • I mean, I don't wanna spring to keep track of my non-managed beans in case someone decicdes to ask them to be autowired (e.g.: `@Autowire NonManagedClass`) – João Pedro Schmitt Aug 20 '20 at 10:51
  • 1
    Why would it? It isn't registering anything it is only auto wiring the bean itself. If you want to make it part of the context you would need to do `registerBean`. – M. Deinum Aug 20 '20 at 11:43