I'm not sure it's a feature or bug, test against 6.1.4.

Field injection:

import java.util.List;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;

@SpringJUnitConfig
@ContextConfiguration(classes = ConstructorInjectTests.Config.class)
public class ConstructorInjectTests {

    @Autowired
    Service service;

    @Test
    void test() {
    }

    static class Config {

        @Bean
        Service service() {
            return new Service();
        }
    }

    public static class Service {

        @Autowired
        List<String> strings;

        public Service() {

        }

    }

}

Exception is thrown as expected:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.util.List<java.lang.String>' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1880)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1406)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1353)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:784)
    ... 90 common frames omitted

Constructor injection:

import java.util.List;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;

@SpringJUnitConfig
@ContextConfiguration(classes = ConstructorInjectTests.class)
@ComponentScan
public class ConstructorInjectTests {

    @Autowired
    Service service;

    @Test
    void test() {
    }

    @Component
    public static class Service {

        public Service(List<String> strings) {

        }

    }

}

Empty List is injected instead of throwing exception.

Factory method injection:

import java.util.List;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;

@SpringJUnitConfig
@ContextConfiguration(classes = ConstructorInjectTests.Config.class)
public class ConstructorInjectTests {

    @Autowired
    Service service;

    @Test
    void test() {
    }

    static class Config {

        @Bean
        Service service(List<String> strings) {
            return new Service(strings);
        }
    }

    public static class Service {

        public Service(List<String> strings) {

        }

    }

}

Empty List is injected instead of throwing exception.

Comment From: snicoll

It's not about field or constructor injection, but about @Autowired being applied on a single injection type vs. a constructor that takes an arbitrary number of arguments. @Autowired has required set to true by default so you're getting exactly what you asked.

Comment From: quaff

It's not about field or constructor injection, but about @Autowired being applied on a single injection type vs. a constructor that takes an arbitrary number of arguments. @Autowired has required set to true by default so you're getting exactly what you asked.

I'm not sure I understand you fully, for field injection it's exactly what I expected throwing exception, but for constructor injection it should not inject empty list since I didn't put @Autowired(required = false).

@SpringJUnitConfig
@ContextConfiguration(classes = ConstructorInjectTests.class)
@ComponentScan
public class ConstructorInjectTests {

    @Autowired
    Service service;

    @Test
    void test() {
    }

    @Component
    public static class Service {

        public Service(List<String> strings) {

        }

    }

}

The test should throw exception but not.

Comment From: jhoeller

As of 5.1, this is intentional for such single-constructor (or equivalent factory method) scenarios as far as we would not be able to construct the bean at all otherwise: see #19901.

Since constructors are not commonly annotated for dependency injection purposes, we have no strict notion of required there anymore. And even if a constructor is annotated with @Autowired(required=false), that is effectively overridden by the constructor being the only one available which implicitly makes it required.

For field and method injection, we back out of such methods if an argument is not resolvable since it is fine to simply skip such injections points. Whereas for constructors and factory methods with their showstopper characteristics (and potential overloading etc.) we always had a different algorithm in place that got refined in 5.1 there.

Comment From: quaff

Would it be better inject empty list/set/map for field injection?

BTW, Does it documented somewhere? I didn't find anything related in https://docs.spring.io/spring-framework/reference/core/beans/dependencies/factory-collaborators.html#beans-constructor-injection