2

I'm trying to find the most direct way to satisfy a dependency of type Function<String, MyObject>. There happens to already exist a class with a static method that conforms to this exact signature. I'd like to wire the two directly together without needing to create any glue objects, configurations, or services and ideally via Spring IoC XML bean configuration.

An example probably illustrates this best.

public class MyObject {

}
public class MyStaticFactoryClass {
    public static MyObject create(String value) {
        // ...
    }
}
@Component("com.example.MyConsumer")
public class MyConsumer {
    public MyConsumer(Function<String, MyObject> factory) {
        // ...
    }
}

Based on the above example I found examples out there for how to achieve this by creating specialized methods on spring configuration classes that return an instance that conforms to the functional interface Function<String, MyObject>. An example is the one the Spring Pivotal documentation pages but as mentioned before I'd rather specify this dependency relationship through the XML config due to constrains of my current project. Additionally it seems that I should be able to wire these things up directly without undue boilerplate or extra abstractions in between seeing that MyStaticFactoryClass.create already conforms to the necessary interface of the dependency.

Below is an example of what consider an undesirable workaround until I can find a better more direct way to configuring the dependency if it exists.

public class FactoryHelper {
    public static <TStatic, TParam, TResult> Function<TParam, TResult> factoryFactory(Class<TStatic> factoryClass, String methodName) {
        return (TParam parameter) -> {
            try {
                return (TResult)factoryClass.getDeclaredMethod(factoryMethod, x.getClass()).invoke(null, x);
            } catch(Exception ex) {
                throw RuntimeException(ex);
            }
        };
    }
}
    <bean id="factoryClass" class="java.lang.Class" factory-method="forName">
        <constructor-arg value="com.example.MyStaticFactoryClass" />
    </bean>

    <bean id="factory" class="com.example.FactoryHelper" factory-method="factoryFactory">
        <constructor-arg ref="factoryClass" />
        <constructor-arg value="create" />
    </bean>
    
    <bean id="consumer" class="com.example.MyConsumer" >
        <constructor-arg ref="factory"/>
    </bean>

Related resources I've reviewed so far:

jpierson
  • 16,435
  • 14
  • 105
  • 149
  • 2
    I don’t think this is possible because Spring DI manages *beans* or collections thereof. `Function` isn’t a bean. If you’re willing to change your code slightly, you could achieve this using a [FactoryBean](https://www.baeldung.com/spring-factorybean). – Abhijit Sarkar Feb 24 '22 at 06:03
  • 1
    Thanks Abhijit. You're comment reminded me that while `Function` may not be a bean it is just an interface which means that there probably a much simpler implementation to the workaround above at least which just uses a class to implement that interface. Still, not what I was hoping for as it seems that services in spring can be functional interfaces but I can't find any clean way to reference an existing method to extract that interface. – jpierson Feb 24 '22 at 07:06

0 Answers0