If Logback and another SLF4J implementation are both on the classpath
it is possible for the LogbackLoggingSystem to fail to locate
a LoggerContext. Rather than a ClassCastException it is better to
make an assertion with an error message.
Fixes gh-162
User can now do this, for instance:
@Configuration
@PropertySource("classpath:my.properties")
public class MainConfiguration {}
@Configuration
@PropertySource("classpath:foo.properties")
@Profile("foo")
public class FooConfiguration {}
and the "foo" properties ar eonly loaded in the "foo" profile.
If any of the sources has a @PropertySource annotation (or many)
then we can add those properties to the Environment. It's a nice
convenient way of specifying a custom external properties location
for an app.
One problem is that Spring will come along and parse the same
annotations later as part of the @Configuration parsing. The
user has pretty limited control over how that is done, and it
will never be done in a "natural" way for a Boot application
(which would prefer that the default application.properties
is applied *last*, whereas Spring will apply the @PropertySource
last).
To get round that problem we add the property sources with
a different name (key in the PropertySources in Environment),
prefixing named property sources with "boot.", and adding
others with a name that is the same as the resource location
(instead of its description, which is the default for
Spring).
Another problem is that Spring doesn't know about YAML, so
the user is currently restricted to using properties files
with this annotation.
We still need the distinction internally between initial and additional
sources, but the SpringApplication API (getSources()) itself doen't
need to reflect that.
We get more control over the handling and in particular the registration
of the endpoint this way. It was practically impossible to disable the
AgentServlet bean when in a parent context of the management server
because of lifecyce issues - you don't know that the user wants a
separate management server until too late.
This approach also makes it possible to test with spring-test MVC
support.
User can add (a single) beans{} DSL declaration (see GroovyBeanDefinitionReader
in Spring 4 for more detail) anywhere at the top level of an application source
file. It will be compiled to a closure and fed in to the application context
through a GroovyBeanDefinitionReader. Cool!
The example spring-boot-cli/samples/beans.groovy runs in an integration test
and passes (see SampleIntegrationTests).
Reinstate initializeWithSensibleDefaults() on AbstractLoggingSystem
beforeInitialize(). This is required to ensure no superfluous logging
output occurs when starting up a spring boot application from the
command line.
It appears that commit e9c649dfb2
modified the logic in an attempt to prevent double initialization.
fixes gh-174
Remove system properties when testing strict property binding. This
prevents test failures that can occur if the local environment happens
to have certain environment variables defined.
Previously all EventListeners were eagerly instantiated
but that can cause problems because it happens quite early
in the lifecycle. Better to be explicit about the
supported types.
* Underscores are allowed as nested property field separators
* System and env vars are only considered for binding if they
look like they apply to a given bean when ignoreUnknownFields
is false
@ConfigurationProperties(ignoreUnkownFields=false,ignoreNestedFields=true)
is now a useful option for binding to "top-level" command line options
(without a prefix). In that case we don't try to bind to `server.*` and
other common prefixed property values (at the cost of not being able to
bind to nested beans).
This leverages existing capabilities of teh JDK and the OS
to grab a port at random and not have it stolen by another
process. It's very hard to avoid that race condition in
pure Java code, so why bother?
User can set port<0 to disable autoStart of connectors (e.g.
to start a web application context but not have it listen on
any port). In that case the actual socket port will be set to
0 (and therefore if it ever starts up the local port will
be random).
The AutoConfigurationReportLoggingInitializer wasn't working in
non-GenericApplicationContext becasue teh BeanFatcory wasn't available
for registering its listener during initialization. Instead of
relying on that rather fragile state I decided to give any
ApplicationContextInitializer that was itself an ApplicationListener
an explicit callback with a ContextRefreshedEvent, and move that
interface up a level in the logging initializer. Works much better.