Home > Back-end >  spring converter not found after adding dependency
spring converter not found after adding dependency

Time:07-26

I have an existing spring (5.3.9) converter. It is a state-less converter: no members, empty default constructor. With this form, it gets picked up and works well with my system:

class Conv implements Converter<A, B> {
    public B convert(A a) {
    ...
    }
}

When adding a state to this converter (any reference to another bean):

class Conv implements Converter<A, B> {
    // the state
    private final X x; 

    public Conv(X x) {
        this.x = x;
    }
    public B convert(A a) {
    ...
    }
}

... The Problem: now, the converter cannot be found at runtime:

No converter found capable of converting from type [A] to type [B]

The converter itself gets to be created successfully and is still picked up by the lifecycle. The dependency gets to be injected well and it exists (stood in debug inside the constructor). There aren't any exceptions in the bean initialization process. I have tried using construction injection; @Autowired injection - I am getting the same behavior.

Finally, after discussing with a colleague, he suggested adding @Lazy to the constructor's argument:

class Conv implements Converter<A, B> {
        // the state
        private final X x; 
    
        public Conv(@Lazy X x) {
            this.x = x;
        }
        public B convert(A a) {
        ...
        }
    }

Amazingly, it solved the problem! the converter can now be found and used as was before adding the state.

(update: I wasn't able to create a minimal example that reproduces this problem. it is probably related somehow to my real beans dependencies..).

Can you explain why @Lazy did the trick?

CodePudding user response:

The problem is that a Converter needs to be registered at a certain time in the lifecycle. Adding a dependency to it has changed the point at which this converter can be created.

Now when adding @Lazy the construction can be done at the right time again as the dependency will now only be used/detected when the dependency is used. The @Lazy will make a proxy of the dependency and when used will at that point do an ApplicationContext.getBean call instead of when constructing the object.

So basically it has to do with where in the lifecycle of the context the object can be constructed if it can be used or not.

  • Related