Skip to content

@EnableResilientMethods does not participate in globally enforced target class proxying #35863

@rafaljaw

Description

@rafaljaw

After upgrading from spring boot 3.5.7 to 4.0.0 I am unable to get beans from BeanFactory.

I have classes A1, A2, A3... implementing interface A. In old code implementation of A is selected at runtime dynamically based on request context using BeanFactory:

public A getA(String version) {
  return switch (version) {
    ...
   case "5" -> beanFactory.getBean(A5.class);
  }
}

This code now throws BeanNotOfRequiredTypeException because actual type is class jdk.proxy1.$Proxy....

When I add annotation @ Proxyable(TARGET_CLASS) to all my A1..An classes, everything starts working as previously.

Below fully working example with incorrect behavior with slightly different exception, but I believe this is the same root cause:

package com.example.demo;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.resilience.annotation.EnableResilientMethods;
import org.springframework.resilience.annotation.Retryable;
import org.springframework.stereotype.Component;

@EnableResilientMethods
@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    interface A {
        int getValue();
    }

    @Component
    class A1 implements A {

        @Retryable
        @Override
        public int getValue() {
            return 1;
        }
    }

    @Component
    class A2 implements A {

        @Retryable
        @Override
        public int getValue() {
            return 2;
        }
    }

    @Bean
    public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
        return args -> {

            try {
                BeanFactory beanFactory = ctx;
                var myA = beanFactory.getBean(A1.class);
                System.out.println(myA.getClass());
                System.out.println(myA.getValue());
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        };
    }
}

After commenting out '@EnableResilientMethods' - everything works.

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)type: bugA general bug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions