Skip to content
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

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

Closed
spring-issuemaster opened this issue Dec 8, 2016 · 3 comments

Comments

@spring-issuemaster
Copy link
Collaborator

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:

  • #19532 Self reference fallback in 4.3 is not meant to apply to collection elements
  • #19692 Modification in AbstractAutowireCapableBeanFactory to prevent stackoverflow errors causes context not to load.

Referenced from: commits 547b963, 4571975

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

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-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Dec 9, 2016

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-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Dec 9, 2016

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
Projects
None yet
2 participants
You can’t perform that action at this time.