Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 362
sbrattla Avatar asked Mar 15 '16 11:03

sbrattla


People also ask

Which of the following can be annotated with @autowired in Spring?

@Autowired annotation can be applied on variables and methods for autowiring byType. We can also use @Autowired annotation on constructor for constructor based spring autowiring. For @Autowired annotation to work, we also need to enable annotation based configuration in spring bean configuration file.

What is the actual use of @autowired @qualifier @component annotation?

There may be a situation when you create more than one bean of the same type and want to wire only one of them with a property. In such cases, you can use the @Qualifier annotation along with @Autowired to remove the confusion by specifying which exact bean will be wired.

Can we Autowire @component class?

Notice how we annotate our example classes with @Component. This registers our class as a Spring bean. Autowiring automatically wires managed beans with other managed beans. Autowiring makes DI even easier with Spring applications because you don't have to explicitly inject managed dependencies.

How do you Autowire annotation in Spring?

Enabling @Autowired annotation Spring beans can be declared either by Java configuration or XML configuration. By declaring beans, you provide metadata to the Spring Container to return the required dependency object at runtime. This is called Spring Bean Autowiring.


1 Answers

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();
    }
}
like image 96
mhlz Avatar answered Oct 20 '22 07:10

mhlz