Sorry if bad formatted or explained, it is my first issue in a third party project.

Recently I've been dragged in the wormhole discussion on dynamic generating and autowiring beans. All the suggestions revolve around using BeanFactory/ApplicationContext with the infamous .getBean() method or the recent ObjectProvider for aquiring a bean, wiring a factory and calling it yourself, or even worse dynamically registering beans for lazy-loading later on. All this alternatives seem cumbersome, unsafe, or feel just like manual wiring with extra steps.

My suggestion is to allow bean generating methods/constructors to have an argument of the type Qualifier, and so, as it is resolving, it receives the argument from the injection point annotation. Example:

@Configuration 
public class Config {

    @Bean @Scope("prototype")
    public Vehicle coloredVehicle(Qualifier color) {
        return new Vehicle(color.value());
    }
}

@Component
public class Vehicle {

    public final String color;

   public Vehicle(String color){
       this.color = color;
    }
}

@Service
public class VehicleService{

    private Vehicle myVehicle;

    @Autowired
    public VehicleService(@Qualifier("red") Vehicle myVehicle){
        myVehicle = this.myVehicle;
    }

}

That alone is a shitty idea, but when paired with custom qualifiers, it could get interesting:

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface VehicleConfig {
    String color();
    int numWheels();
}

@Configuration 
public class Config {

    @Bean @Scope("prototype")
    public Vehicle coloredVehicle(VehicleConfig config) {
        return new Vehicle(config.color(), config.numWheels());
    }
}

@Component
public class Vehicle {

    public final String color;
    public final int numWheels;

   public Vehicle(String color, int numWheels){
        this.color = color;
        this.numWheels = numWheels;
    }
}

@Service
public class VehicleService{

    private Vehicle myVehicle;

    @Autowired
    public VehicleService(@VehicleConfig(color="red",numWheels=2) Vehicle myVehicle){
        myVehicle = this.myVehicle;
    }

}

Doing so would allow beans which could not be constructed otherwise to be injected in a type-safe and concise manner, with very clear semantics, without using the .getBean() overloaded method.

Perhaps if it would be too hard to implement this way, with the IoC having to understand and differentiate when should the qualifier filter the possible beans and when it should be passed as an argument to a bean generating method, another annotation could be proposed to achieve the same results.

I understand my example is a bit too simple and may not entirely illustrate the possibilities that can be achieved, but imagine the sheer power of writing something like private @Autowired @PoolSize(2) ThreadPoolService poolService; or private @Autowired @RemoteTarget(host="111.222.333.444:555") RemoteResourceConsumerService remoteConsumer; in a service.

Unfortunately I come to you with no knowlege of the internal mechanisms of the IoC, and as such, with no proper implementation instructions for my suggestion, but I hope the community can see this issue and further expand it or come up with concrete plans for it.

Comment From: mdeinum

Couldn't you already achieve this by using the InjectionPoint as a method argument. That gives you all the information (type, name etc. etc.) of the place the bean needs to be autowired. You can retrieve the annotations with that as well (just inspect the type). That seems more powerful then only allowing the @Qualifier.

@Bean @Scope("prototype")
 public Vehicle coloredVehicle(InjectionPoint ip) {
  Qualifier color = ip.getAnnotation(Qualifier.class);
  return new Vehicle(color.value());
}

And for the future you probably want to ask things like this on StackOverflow and not the Spring issue tracker.

Comment From: ClauCalv

Thanks for the suggestion, I wasn't aware about the injectionPoint argument, it really solves the problem. But I firmly believe most people didn't know as well, because I spent two whole days on StackOverflow searching on this topic and all the answers were using the unsafe/cumbersome methods I explained in the intro of the issue.

I believe this settles the case. The enhancement proposed could still be useful, but now is no more necessary and only saves a single line of code and not worth implementing. Thanks for your time.

Comment From: mdeinum

It is mentioned in the Spring Reference Guide in the end of that section. This also mentioned it is available since Spring 4.3 so if you have answers/questions with older versions of the framework that will differ.