spring-attic / spring-native

Spring Native is now superseded by Spring Boot 3 official native support
https://docs.spring.io/spring-boot/docs/current/reference/html/native-image.html
Apache License 2.0
2.74k stars 356 forks source link

AutowireCapableBeanFactory is not injecting beans via setters with `@Autowired(required =false)` #666

Closed alek-sys closed 3 years ago

alek-sys commented 3 years ago

See this https://github.com/alek-sys/spring-security-native-issue/ repository for more details, short summary is: AutowireCapableBeanFactory is working differently in native / non-native apps when injecting beans via setters.

E.g. when a bean with a setter with @Autowired(required = false) is used, JVM version gets a bean injected, but native version doesn't.

For context, but kind of irrelevant: I noticed that while trying to compile Spring Authorization Server to a native image and found that OAuth2AuthorizationServerConfigurer gives different configurations in native / JVM setup. Basically this setter isn't called here and generated ID token is missing iss token claim.

aclement commented 3 years ago

It looks like what i suspected, the thing annotated is not exposed for reflection so the autowired annotation is not seen. At least I can fix your sample (thanks for that!) by including this on the SpringBoot application:

@TypeHint(
  types = AnotherBean.class,
  methods = @MethodHint(name = "setSomeBean",parameterTypes = SomeBean.class ))

I'm not a great fan of Autowireds somewhat 'hidden' in classes as we aren't really digging around for them that deeply. The other fix is to make AnotherBean an @Component. We need to work out the appropriate way to deal with this, hmm.

aclement commented 3 years ago

A similar fix for the real scenario would then be:

@TypeHint(types = OAuth2AuthorizationCodeAuthenticationProvider.class,
  methods = @MethodHint(name="setProviderSettings",parameterTypes=ProviderSettings.class))

What I've tried to do is fold that hint into Spring Native. If you try with a 0.9.2 release tomorrow it should pick it up - let me know if it doesn't behave (because I've not got the full setup to try it out) or you can use the hint above to workaround I hope.

alek-sys commented 3 years ago

Thanks @aclement! I'm not a fan of method / property injection as well, but I think it's fairly common in some apps, I've seen it at least a couple of times in Spring Secruity.

@TypeHint worked perfectly for my demo app, now trying that out with Auth-z Server.

UPDATE: Worked like a charm on Auth-z server as well.