Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does class gets injected which implements interface method being called in Java or Groovy code?

I have below working groovy code from Spring framework project:

import org.springframework.oxm.Unmarshaller

public class ItemSearchService  {
    Unmarshaller unmarshaller;
    public ItemSearchResponse getObject(InputStream xml) {
    
        ItemSearchResponse its = null;
        try {
            its = (ItemSearchResponse) unmarshaller.unmarshal(new StreamSource(xml));
        } finally {
        }
        return its;
    }
}

Unmarshaller.unmarshall is actually interface method: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/oxm/Unmarshaller.html

Unmarshaller interface is implemented by several classes.

Who decides which implementing class to inject during runtime and how it decides which class to use?

Does Spring IoC mechanism does this? If so does it pick up one specific implementing class during build time when jar is generated or it does it during run time?

Also how to know which implementing class it actually used?

Will above code work outside of Spring in ordinary Java file assuming dependent jars in classpath?

like image 422
ace Avatar asked Oct 24 '20 16:10

ace


People also ask

What is @inject annotation in Java?

@Inject annotation is a standard annotation, which is defined in the standard "Dependency Injection for Java" (JSR-330). Spring (since the version 3.0) supports the generalized model of dependency injection which is defined in the standard JSR-330.

What is Interface injection?

In my understanding, interface injection describes the ability of a bean contener to inject a new interface to the bean, no matter that the class definition of this bean is not implementing it. All examples presented here show how to create a bean out of concrete class, and then how to inject it into another bean.

How do you call a class in Groovy?

In Groovy we can add a method named call to a class and then invoke the method without using the name call . We would simply just type the parentheses and optional arguments on an object instance. Groovy calls this the call operator: () . This can be especially useful in for example a DSL written with Groovy.


1 Answers

As soon as it goes about a Grails project (not a pure Spring one), some things should be clarified.

Who decides which implementing class to inject during runtime and how it decides which class to use? Does Spring IoC mechanism does this? If so does it pick up one specific implementing class during build time when jar is generated or it does it during run time?

What Spring does in a plain Spring(Boot) is nicely described by @svr s answer and other documentation on the Internet, but has not much to do with your case.

In Grails the convention-over-configuration doctrine is used, meaning that

  • by default Bean Autowiring is active
  • only beans which are declared as Grails artefacts, like Service are auto-injected.

Usually, if you want to autowire a bean of other stereotype, you have to declare it somewhere, otherwise Spring IoC container inside Grails simply won't find it.

You shall check your grails-app/conf/spring folder for resources.groovy (or maybe yaml or xml files depending on version ) and see if your unmarshaller bean is defined there. It should look like:

beans = {
  unmarshaller Unmarshaller ....
}

So, basically it doesn't matter how many implementations of Unmarshaller interface are present in all project's jar files. The only thing what matters is what defined in your resources.groovy.

If you want to check the class of the bean in runtime, just log it's class in your service:

class ItemSearchService  {
  Unmarshaller unmarshaller
  ItemSearchResponse getObject(InputStream xml) {
     log.info "unmarshaller's class is $unmarshaller.class"
     // or
     // println "unmarshaller's class is $unmarshaller.class"
  }
}  
like image 59
injecteer Avatar answered Oct 28 '22 12:10

injecteer