spring-attic / spring-init Goto Github PK
View Code? Open in Web Editor NEWLicense: Apache License 2.0
License: Apache License 2.0
I thought this was working (something changed to do with build time initialization in native-image?), but currently no native image works with closedWorld=false
because the InitializerLocator
always returns null for all initializers.
Spring Framework doesn't really support this use case in functional beans (but it does with @Autowired
), so we either need new features there, or some convenience methods here. There's a failing test in modules/fails.
We have custom binders for @ConfigurationProperties
but @Bean
methods still require reflective access in functional mode. Probably we can short circuit that by setting the target type of the bean definition.
As implemented in Spring Fu autoconfigure-adapter
, it is probably not necessary to create beans for configuration classes (for example context.registerBean(SampleConfiguration.class)
of the README). It "pollutes" the application context with unnecessary beans and increase the footprint with no real benefits.
For the general use case, I think it is safe to instantiate by default configuration classes at ApplicationContextInitializer#init
level with a simple new
. When laziness is needed for example for EnableWebMvcConfiguration
, it should be possible to use a Supplier
to provide laziness without using beans (see related configuration on Spring Fu side):
Supplier<EnableWebMvcConfiguration> enableWebMvcConfiguration = new Supplier<EnableWebMvcConfiguration>() {
private EnableWebMvcConfiguration configuration;
@Override
public EnableWebMvcConfiguration get() {
if (configuration == null) {
configuration = new EnableWebMvcConfiguration(...);
configuration.setApplicationContext(context);
configuration.setServletContext(((WebApplicationContext) context).getServletContext());
configuration.setResourceLoader(context);
}
return configuration;
}
};
We could maybe turn this specific example to something more generic capable of providing lazily multiple configuration instances.
Identifying where such pattern is needed could be done by detecting automatically where this is needed if possible, else by configuring a list of classes where we need to do that.
Notice that ultimately, both configuration classes and methods are not needed to be retained at runtime, the most optimal solution would be to inline configuration method bodies in the functional bean registration lambdas, but this is probably outside of the scope of this issue and could be do later as an optimization.
Please upgrade to Spring Boot 2.4.0.RC1 since we need this to release spring-graalvm-native
0.8.2.
Might need some changes in Spring Boot, but progress can probably be made by generating a BeanPostProcessor
that knows about all the @ConfigurationProperties
in the classpath.
@Autowired
methods actually work fine already because of the AutowiredAnnotationBeanPostProcessor
. But it would be nice to have a non-reflective version of that.
Some beans that are not @Configuration
carry @Conditions
(e.g. CacheAutoConfiguration.CacheManagerEntityManagerFactoryDependsOnPostProcessor
). Currently we don't add the condition processing so runtime errors can occur.
So far it hasn't been an issue, but Spring Boot has a couple of explicit @Bean
names (e.g. the whitelabel error view).
The GeneratedTypeService
doesn't container package private @Component
classes yet. So an app with such classes works in a JVM but not if the types are not available reflectively.
There's a vulnerability in 5.3.2, and also some changes that switch to using lite @Configuration
so that will help this project.
The generated properties file is kind of ugly because it has one long line with everything on it. If we could use continuation markers that would work better.
spring-fu
and spring-graalvm-native
are about to switch on Spring Boot 2.4.0-SNAPSHOT
in order to benefits from Spring Framework 5.3.0-M1
(about to be released) GraalVM native improvement, and Spring Fu will switch as well.
Could you please switch spring-init
to Spring Boot 2.4.0-SNAPSHOT
in order to allow spring-fu
and spring-graalvm-native
to leverage it? There should be very few differences compared to 2.3.
Not all existing @Configuration
classes are mirrored in spring-init (currently only Spring Boot and Spring Security), so when new projects are needed and they don't have functional bean initializers, might it be possible to introduce those dependencies and gradually migrate to fully functional beans?
There is also the question of what to do with @Configuration
that does not have proxyBeanMethods = false
. Technically it's an error to use such classes with spring-init currently - nothing will break necessarily, but self-invocations of @Bean
methods might lead to unexpected results (e.g. multiple instances of "singleton" beans in the class loader).
There's a failing test in modules/fails.
In order to be effective for GraalVM native code removal, the enabled
flag introduced in 0b6427e should also defines build time init for initializer classes.
This can be done with a META-INF/native-image/org.springframework.boot/autoconfigure/native-image.properties
file defining:
Args = --initialize-at-build-time=com.example.Initializer1,com.example.Initializer2
Currently the "actuator" sample is fully functional (a native image can be built with spring.native.mode=functional
) but only with some manually maintained JSON. We could use a @Hint
or something. Or build it into spring-graalvm-native.
The "core" library in spring-init has some experiments with modular configuration (@SpringInitApplication
and the *Configurations
). It would be better to extract those to a separate module so they don't obscure the build-time code generation features in this repo.
In FunctionalInstallerPostProcessor could you please make XmlInitalizer
removable at buildtime in order to allow us to remove this substitution?
Something like replacing:
} else if (imported.getResources() != null) {
initializers.add(new XmlInitializer(imported.getResources()));
}
by
private static final boolean shouldIgnoreXml = SpringProperties.getFlag("spring.xml.ignore");
// ...
} else if (shouldIgnoreXml && imported.getResources() != null) {
initializers.add(new XmlInitializer(imported.getResources()));
}
With FunctionalInstallerPostProcessor
initialized at build time.
Up to now all the sample apps could use @ImportAutoConfiguration
and order the classes manually. But now I want to break up the PetClinic app and put some of the autoconfigs in a separate @Profile
, and it turns out that falls down because the order is not respected when the initializers are finally executed.
It's hard to get this right because initializers call other initializers, which themselves might add imports.
Anything that started off as an @ImportAutoConfiguration
needs to wait till the end and then order strictly according to the standard Spring Boot algorithm.
I see test failures in the "auto" sample to do with actuator properties binding when I try to switch to functional. Not sure why yet.
I'd like to try out this project, but it seems it's only available in maven. Looking at the amount of code in the maven plugin it looks quite reasonable to port it to a gradle plugin.
If it gets ported over to gradle, a thing to keep in mind would be that it should be strongly typed (so use Action
s for example if needed), so it works with the Gradle Kotlin DSL (should be working out of the box if the plugin is written in java or kotlin).
https://docs.gradle.org/current/userguide/custom_plugins.html
You're using maven, so this might help: https://stackoverflow.com/a/27556212/8220327
When a @Configuration
class already has an initializer (where it matches the naming convention), we should back off and not generate one. There is a failing test in modules/fails.
After a dedicated discussion with Spring Framework team about enabling or not functional only web configuration, it seems it is not going to happen in Spring Framework 5.3 timeframe, it raises too much open questions and seems a better fit for Spring Framework 6.
So my proposal is to perform a build-time analysis of the application and ignore beans like RequestMappingHandlerMapping
and other annotation based ones when no @Controller
and @RequestMapping
are found, and when actuators are not used.
Notice the actuator efficiency will be explored and discussed as part of spring-attic/spring-native#259. I think there is also a point related to Boot error handling potentially.
It should allow removal of explicit configurations without a footprint regression in our GraalVM native support. This would also remove our last blocking point on spring-projects-experimental/spring-fu#273.
Spring Security has its own @Configuration
classes that we probably need to functionalize.
XmlInitializer
usage should probably be conditional behind a -Dspring.xml.ignore
check in order to avoid increasing the native image size.
I noticed in the "secure" sample that you can remove the explicit import of ReactiveUserDetailsServiceAutoConfiguration
and the tests still pass (in @Configuration
mode, not functional). So it's like @EnabelAutoConfiguration
was on by mistake somehow.
Currently this doesn't work:
@Configuration
public class SampleConfiguration {
@Bean
public Foo foo() {
return new Foo();
}
@Bean
public Bar<Foo> bar(Foo foo) {
return new Bar<>(foo);
}
@Bean
public Bar<Collection<Foo>> bars(Foo foo) {
return new Bar<>(Arrays.asList(foo));
}
@Bean
public CommandLineRunner runner(Bar<Foo> bar) {
return args -> {.};
}
@Bean
public CommandLineRunner another(Bar<Collection<Foo>> bar) {
return args -> {.};
}
}
because it tries to generate bean definitions:
bar
and bars
that are simply of type Bar
,runner
and another
that both autowire a plain Bar
Currently the auto-generated binders only work for "simple" properties (non-arrays and non-generics). Easiest to do and having the biggest impact would be String[]
and List|Collection<String>
(e.g. so you can bind DataSourceProperties
in PetClinic).
We have @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
but it looks like it always runs on 8080 to me. Must be a bug.
Duplicating the whole web endpoint infrastructure is probably not worth it, but we might learn something if we do just /info and /health (and things would work well in k8s then too).
There might be nothing we can do here, but you can see the effect on Petclinic (1800ms startup without caching, 2000ms with). Maybe scanning all beans for @Cacheable
?
See spring-attic/spring-native#248 for more details. We could probably start by doing such transformation only on configuration classes without @Bean
to handle the default @SpringBootApplication
case. Step 2 could be to do this transformation only if there is no cross @Bean
method invocation. cc @aclement
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.