Skip to content

Behaviour of field injection for List dependencies that are produced and consumed by the same configuration class has changed in 4.3.5 snapshots [SPR-14996] #19563

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
spring-projects-issues opened this issue Dec 8, 2016 · 3 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: regression A bug that is also a regression
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Dec 8, 2016

Andy Wilkinson opened SPR-14996 and commented

I noticed this in 5.0 as well but didn't think too much of it, however I've just noticed that the latest 4.3.5 snapshots exhibit the same change in behaviour.

Here's small application that will reproduce the problem:

package com.example;

import java.util.List;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.Assert;

public class FieldInjectionBehaviorChange {

	public static void main(String[] args) {
		new AnnotationConfigApplicationContext(ExampleConfiguration.class).close();
	}

	@Configuration
	static class ExampleConfiguration {

		@Autowired(required = false)
		private List<Thing> things;

		@PostConstruct
		public void postConstruct() {
			Assert.notNull(this.things);
		}

		@Bean
		public Thing thing() {
			return new Thing() {};
		}

	}

	interface Thing {

	}

}

It will run successfully with 4.3.4.RELEASE and fail with 4.3.5.BUILD-SNAPSHOT due to things being null.

It also works without required=false with 4.3.4.RELEASE but fails with a NoSuchBeanDefinitionException with 4.3.5.BUILD-SNAPSHOT.

It works with both 4.3.4.RELEASE and 4.3.5.BUILD-SNAPSHOT if the field is Thing rather than List<Thing>.


Affects: 4.3.5

Issue Links:

Referenced from: commits 547b963, 4571975

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Dec 8, 2016

Juergen Hoeller commented

I'm pretty sure that's a side effect of #19532 where we were trying to prevent self references in collections, fixing a regression between 4.2 and 4.3. Seems we're preventing references back to the same configuration class even; I'll see how we can relax that.

Generally speaking, there is a lifecycle problem there though - a kind of circular reference: the thing() factory method semantically requires a fully initialized instance of the configuration class, whereas that initialization requires injection of the thing() return value. Declaring thing() as static or moving it to a different configuration class would solve the problem, wouldn't it?

@spring-projects-issues
Copy link
Collaborator Author

Andy Wilkinson commented

I haven't tried the real-world problem (it's in Boot) with static, but moving it to a separate configuration class does fix it. We did that (and moved to constructor injection at the same time) in Boot 2.0 when I noticed the problem with the 5.0 snapshots. We could do the same here but, strictly speaking, it would be a breaking change as it's a public configuration class that's affected. That said, I don't like our current configuration arrangement. If this behaviour can't be fine-tuned we'll change Boot.

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

We're allowing factory references back to the same bean now, making your scenario work again (also for compatibility with 4.2's behavior). However, we're still not considering a direct self reference (i.e. the very same bean) as a candidate for a dependency collection (like 4.2 didn't either).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: regression A bug that is also a regression
Projects
None yet
Development

No branches or pull requests

2 participants