How do I autowire 3rd party classes with annotations in Spring?
Asked Answered
I

1

12

The majority of examples on Spring Boot I've found focus on building simple web applications. That is, web applications where you are in complete and utterly control of everything.

On the other side, I have not had much luck in finding examples on how to build non-web applications where larger parts of the application depends on 3rd party code.

Consider my com.mypackage.Application class below.

package com.mypackage;

import com.3rdparty.factory.ServiceFactory;

public class Application {

  private final ServiceFactory sf;

  public Application(ServiceFactory sf) {
    this.sf = sf;
  }

  public void doSomeWork() {
    ServiceA sa = sf.getServiceA();
    [...]
}

The Application class simply instantiates DefaultManager and invokes run().

Now, the 3rd party ServiceFactory class has additional dependencies:

package com.3rdparty.factory;

import com.3rdparty.service.ServiceA;
import com.3rdparty.service.ServiceA;

public class ServiceFactory {

  private final ServiceA sa;
  private final ServiceB sb;

  public ServiceFactory(ServiceA sa, ServiceB sb) {
    this.sa = sa;
    this.sb = sb;
  }

  public ServiceA getServiceA() {
    return sa;
  }

  public ServiceB getServiceB() {
    return sb;
  }

}

I could launch Application from a Main class:

import com.mypackage.Application;

public class Main {

  public static void main(String[] args) { 
    ApplicationContext context = new ClassPathXmlApplicationContext("path/to/applicationContext.xml");
    Application app = (Application) context.getBean("app");
    app.doSomeWork();
  }

Question : how do I inject ServiceA and ServiceB into ServiceFactory. This is a 3rd party class, I have no control over it, and I can't modify it. Thus, I can't add any annotations.

I can easily get this to work with XML configuration, but considering that annotations seems to be the "best practise" way of doing it these days I'd like to know how I can get this to work with annotations.

If the annotation way of doing this involves a large amount of code, then I'd like to know what advantages this gives me compared to the XML configuration which I think is quite easy to comprehend; and a pattern which is easy to get going with across different projects.

Ide answered 15/3, 2016 at 11:51 Comment(0)
K
23

You need to define a @Configuration class that builds the SomeFactory as a Bean:

@Configuration
class SomeFactoryConfiguration {
    @Bean
    public ServiceFactory serviceFactory() {
        return new ServiceFactory(/* create/get ServiceA and ServiceB somehow */):
    }
}

This will expose this ServiceFactory instance as a Bean in your spring application that you can simply autowire.

If you want you can create ServiceA and ServiceB as Beans as well and then reference them in your creation of the ServiceFactory:

@Configuration
class SomeFactoryConfiguration {
    @Bean
    public ServiceFactory serviceFactory() {
        return new ServiceFactory(serviceA(), serviceB()):
    }
    @Bean
    public ServiceA serviceA() {
        return new ServiceA();
    }
    @Bean
    public ServiceB serviceB() {
        return new ServiceB();
    }
}
Korry answered 15/3, 2016 at 11:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.