Overview

  • Version : 6.2.0
  • Cause: #33051

The change to prevent @Autowired on a @Bean method prevents the following use case.

Before I go change all the code to reflect the new limitations I want to make sure this was an intended side effect.

Use Case

Create an annotation like:

@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Autowired
@Qualifier("transactionManager1") 
public @interface Tx1Manager { //Imagine we have 3 versions of this annotation

}

Use the annotation when setting up @Configuration.

public class FooConfig {
    @Bean
    @Tx1Manager
    PlatformTransactionManager tx1Manager() {
       ///... code omitted
    }

    @Bean
    @Tx2Manager
    PlatformTransactionManager tx2Manager() {
       ///... code omitted
    }
}

Use the annotation in a variety of contexts.

public class ConstructorInjected {

    public ConstuctorInjected(@Tx1Manager PlatformTransactionManager tx1Manager) {
    }
}

public class FieldInjected {
   @Tx1Manager 
   PlatformTransactionManager tx1Manager;

}

public class SetterInjected {
    PlatformTransactionManager tx1Manager;

    public setTtx1Manager(@Tx1Manager PlatformTransactionManager tx1Manager) {
    }
}

After this change I will remove @Autowired from the annotation class and selectively add to FieldInjected and SetterInjected use cases.

My question is:

Was the change worth it?

Or is it worth undoing the change to save me and others from having to rework our code bases?

I'll refactor everywhere if I need to, but it didn't look like #33051 discussed this side effect.

Comment From: sbrannen

Hi @harmonic-ben,

@Autowired has never been supported (in production code [1]) on constructor or method parameters. Thus, in both 6.1.x and 6.2, the @Autowired meta-annotation is ignored for the ConstuctorInjected constructor as well as for the setTtx1Manager() method in SetterInjected. Furthermore, the latter actually fails on 6.1.x, since the setTtx1Manager() method itself needs to be annotated with @Autowired (or @Tx1Manager).

In other words, prior to 6.2, @Autowired was only adding value for your autowiring use cases when @Tx1Manager was applied directly on a field, setter method, or constructor.

In addition, meta-annotating @Bean methods with @Autowired results in those methods being invoked twice, which is undesirable.

In light of that, I would generally recommend removing @Autowired from your @Tx*Manager qualifier annotations.

In any case, we will brainstorm within the team and get back to you.

Cheers,

Sam


[1] @Autowired is only supported on constructor and method parameters for integration tests when using the SpringExtension for JUnit Jupiter.

Comment From: harmonic-ben

Cool I have enough guidance to know its probably not a great idea and will clean it up in our codebase. Will leave this open in case you decide something different.

Comment From: sbrannen

Cool I have enough guidance to know its probably not a great idea and will clean it up in our codebase. Will leave this open in case you decide something different.

Thanks for the feedback, @harmonic-ben. 👍

In end the end, we have decided to leave things as-is, since the use of @Autowired as a meta-annotation on @Bean methods is semantically incorrect.

In light of that, I'm closing this issue.

Cheers,

Sam