[bs-92] Add simple main wrapper for SpringApplication

* Added Spring class
* Used in demo project in README
* Also fixed cycle in spring-bootstrap jar

[Fixes #49121565]
pull/1/merge
Dave Syer 12 years ago
parent 0a730beb2a
commit 504d96eb51

@ -195,9 +195,9 @@
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0.2</version>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.1.Final</version>
</dependency>
<dependency>
<groupId>junit</groupId>

@ -12,6 +12,7 @@
<properties>
<main.basedir>${project.basedir}/..</main.basedir>
<spring.bootstrap.version>0.0.1-SNAPSHOT</spring.bootstrap.version>
<start-class>org.springframework.bootstrap.main.Spring</start-class>
</properties>
<modules>
<module>spring-bootstrap-application</module>

@ -55,7 +55,6 @@ If you are using Maven create a really simple `pom.xml` with 2 dependencies:
</parent>
<properties>
<spring.bootstrap.version>0.0.1-SNAPSHOT</spring.bootstrap.version>
<start-class>org.springframework.bootstrap.SpringApplication</start-class>
</properties>
<dependencies>
<dependency>
@ -139,11 +138,14 @@ endpoint. An endpoint can be implemented as a Spring MVC
You can launch that straight away using the Spring Bootstrap CLI
(without the `@EnableAutoConfiguration` and even without the import
statements that your IDE will add if you are using one), or you can
use the main method to launch it from your project jar. Just change
the `start-class` in the `pom` above to the fully qualified name of
your `SampleController`, e.g.
use the main method to launch it from your project jar. Just add a
`start-class` in the properties section of the `pom` above pointing to
the fully qualified name of your `SampleController`, e.g.
<start-class>com.mycompany.sample.SampleController</start-class>
<properties>
<spring.bootstrap.version>0.0.1-SNAPSHOT</spring.bootstrap.version>
<start-class>com.mycompany.sample.SampleController</start-class>
</properties>
and re-package:

@ -16,6 +16,7 @@
package org.springframework.bootstrap.autoconfigure.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.bootstrap.context.annotation.ConditionalOnClass;
import org.springframework.bootstrap.context.annotation.ConditionalOnMissingBean;
import org.springframework.bootstrap.service.audit.AuditEventRepository;
import org.springframework.bootstrap.service.audit.InMemoryAuditEventRepository;
@ -47,11 +48,13 @@ public class AuditConfiguration {
}
@Bean
@ConditionalOnClass(name = "org.springframework.security.authentication.event.AbstractAuthenticationEvent")
public AuthenticationAuditListener authenticationAuditListener() throws Exception {
return new AuthenticationAuditListener();
}
@Bean
@ConditionalOnClass(name = "org.springframework.security.access.event.AbstractAuthorizationEvent")
public AuthorizationAuditListener authorizationAuditListener() throws Exception {
return new AuthorizationAuditListener();
}

@ -27,8 +27,8 @@
</dependency>
<!-- Optional -->
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<optional>true</optional>
</dependency>
<dependency>
@ -119,6 +119,22 @@
<optional>true</optional>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.0.0.GA</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>

@ -27,10 +27,6 @@ import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.bootstrap.autoconfigure.batch.BatchAutoConfiguration;
import org.springframework.bootstrap.autoconfigure.data.JpaRepositoriesAutoConfiguration;
import org.springframework.bootstrap.context.annotation.EnableAutoConfiguration;
import org.springframework.bootstrap.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
@ -60,9 +56,8 @@ import org.springframework.web.context.ConfigurableWebApplicationContext;
* application:
*
* <ul>
* <li>Create an appropriate {@link ApplicationContext} instance (
* {@link AnnotationConfigApplicationContext} or
* {@link AnnotationConfigEmbeddedWebApplicationContext} depending on your classpath)</li>
* <li>Create an appropriate {@link ApplicationContext} instance (depending on your
* classpath)</li>
*
* <li>Register a {@link CommandLinePropertySource} to expose command line arguments as
* Spring properties</li>
@ -128,7 +123,7 @@ public class SpringApplication {
private static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context."
+ "annotation.AnnotationConfigApplicationContext";
private static final String DEFAULT_WEB_CONTEXT_CLASS = "org.springframework.bootstrap."
public static final String DEFAULT_WEB_CONTEXT_CLASS = "org.springframework.bootstrap."
+ "context.embedded.AnnotationConfigEmbeddedWebApplicationContext";
private static final String[] WEB_ENVIRONMENT_CLASSES = { "javax.servlet.Servlet",
@ -499,9 +494,8 @@ public class SpringApplication {
/**
* Sets the type of Spring {@link ApplicationContext} that will be created. If not
* specified defaults to {@link AnnotationConfigEmbeddedWebApplicationContext} for web
* based applications or {@link AnnotationConfigApplicationContext} for non web based
* applications.
* specified defaults to {@link #DEFAULT_WEB_CONTEXT_CLASS} for web based applications
* or {@link AnnotationConfigApplicationContext} for non web based applications.
* @param applicationContextClass the context class to set
* @see #setApplicationContext(ApplicationContext)
*/
@ -512,9 +506,9 @@ public class SpringApplication {
/**
* Sets a Spring {@link ApplicationContext} that will be used for the application. If
* not specified an {@link AnnotationConfigEmbeddedWebApplicationContext} will be
* created for web based applications or an {@link AnnotationConfigApplicationContext}
* for non web based applications.
* not specified an {@link #DEFAULT_WEB_CONTEXT_CLASS} will be created for web based
* applications or an {@link AnnotationConfigApplicationContext} for non web based
* applications.
* @param applicationContext the spring application context.
* @see #setApplicationContextClass(Class)
*/
@ -611,22 +605,4 @@ public class SpringApplication {
}
/**
* A basic main that can be used to launch an autoconfigured application. Useful for
* demos and testing, perhaps less for production use (where the run methods are more
* appropriate).
*
* @param args command line arguments
* @see #run(Object[], String[])
* @see #run(Object, String...)
*/
public static void main(String[] args) {
run(new Class<?>[] { AutoMain.class }, args);
}
@EnableAutoConfiguration(exclude = { JpaRepositoriesAutoConfiguration.class,
BatchAutoConfiguration.class })
public static class AutoMain {
}
}

@ -19,6 +19,7 @@ package org.springframework.bootstrap.autoconfigure.batch;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.bootstrap.CommandLineRunner;
import org.springframework.bootstrap.ExitCodeGenerator;
import org.springframework.bootstrap.context.annotation.ConditionalOnBean;
import org.springframework.bootstrap.context.annotation.ConditionalOnClass;
import org.springframework.bootstrap.context.annotation.ConditionalOnMissingBean;
import org.springframework.bootstrap.context.annotation.EnableAutoConfiguration;
@ -42,12 +43,14 @@ public class BatchAutoConfiguration {
@Bean
@ConditionalOnMissingBean({ CommandLineRunner.class })
@ConditionalOnBean({ JobLauncher.class })
public JobLauncherCommandLineRunner jobLauncherCommandLineRunner() {
return new JobLauncherCommandLineRunner();
}
@Bean
@ConditionalOnMissingBean({ ExitCodeGenerator.class })
@ConditionalOnBean({ JobLauncher.class })
public ExitCodeGenerator jobExecutionExitCodeGenerator() {
return new JobExecutionExitCodeGenerator();
}

@ -22,7 +22,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.bootstrap.bind.PropertySourcesBindingPostProcessor;
/**
* Annotation for externalized configuration. Add this to a class definition if you want

@ -20,7 +20,6 @@ import java.lang.reflect.Field;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.bootstrap.bind.PropertySourcesBindingPostProcessor;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@ -63,7 +63,7 @@ import org.springframework.core.io.support.SpringFactoriesLoader;
public @interface EnableAutoConfiguration {
/**
* Exclude a specific auto-configuration class such that it will never be applied.
* Exclude specific auto-configuration classes such that they will never be applied.
*/
Class<?>[] exclude() default {};

@ -14,12 +14,12 @@
* limitations under the License.
*/
package org.springframework.bootstrap.bind;
package org.springframework.bootstrap.context.annotation;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.bootstrap.context.annotation.ConfigurationProperties;
import org.springframework.bootstrap.bind.PropertiesConfigurationFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.env.PropertySources;

@ -0,0 +1,93 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.bootstrap.main;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.LogFactory;
import org.springframework.bootstrap.SpringApplication;
import org.springframework.bootstrap.context.annotation.EnableAutoConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.SpringVersion;
import org.springframework.util.ClassUtils;
/**
* Very simple main class that can be used to launch an application from sources (class,
* package or XML). Useful for demos and testing, perhaps less for production use (where
* the {@link SpringApplication} run methods are often more convenient).
*
* @author Dave Syer
*
*/
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Spring {
private static ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(
true);
private static ApplicationContext context;
/**
* @return the context if there is one
*/
public static ApplicationContext getApplicationContext() {
return context;
}
/**
* A basic main that can be used to launch an application.
*
* @param args command line arguments
* @see SpringApplication#run(Object[], String[])
* @see SpringApplication#run(Object, String...)
*/
public static void main(String[] args) throws Exception {
List<String> strings = new ArrayList<String>();
List<Object> sources = new ArrayList<Object>();
for (String arg : args) {
if (ClassUtils.isPresent(arg, null)) {
sources.add(ClassUtils.forName(arg, null));
} else if (arg.endsWith(".xml")) {
sources.add(arg);
} else if (!scanner.findCandidateComponents(arg).isEmpty()) {
sources.add(arg);
} else {
strings.add(arg);
}
}
if (sources.isEmpty()) {
sources.add(Spring.class);
}
context = SpringApplication.run(sources.toArray(new Object[sources.size()]),
strings.toArray(new String[strings.size()]));
LogFactory.getLog(Spring.class).info(
"Running Spring " + SpringVersion.getVersion() + " with sources: "
+ sources);
}
}

@ -26,7 +26,6 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.beans.factory.support.DefaultBeanNameGenerator;
import org.springframework.bootstrap.SpringApplication.AutoMain;
import org.springframework.bootstrap.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
import org.springframework.bootstrap.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
import org.springframework.context.ApplicationContext;
@ -153,15 +152,6 @@ public class SpringApplicationTests {
assertThat(getEnvironment().getProperty("foo"), equalTo("bar"));
}
@Test
public void emptytApplicationContext() throws Exception {
// This is the class that will be used for main()
SpringApplication application = new SpringApplication(AutoMain.class);
this.context = application.run();
assertThat(this.context,
instanceOf(AnnotationConfigEmbeddedWebApplicationContext.class));
}
@Test
public void defaultApplicationContext() throws Exception {
SpringApplication application = new SpringApplication(ExampleConfig.class);

@ -0,0 +1,61 @@
/*
* Copyright 2012-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.bootstrap.main;
import org.junit.After;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.util.ClassUtils;
import static org.junit.Assert.assertNotNull;
/**
* @author Dave Syer
*
*/
public class SimpleMainTests {
private ApplicationContext context;
@After
public void close() {
if (this.context instanceof ConfigurableApplicationContext) {
((ConfigurableApplicationContext) this.context).close();
}
}
@Test
public void emptyApplicationContext() throws Exception {
Spring.main(new String[0]);
this.context = Spring.getApplicationContext();
assertNotNull(this.context);
}
@Test
public void basePackageScan() throws Exception {
Spring.main(new String[] { ClassUtils.getPackageName(Spring.class) });
this.context = Spring.getApplicationContext();
assertNotNull(this.context);
}
@Test
public void xmlContext() throws Exception {
Spring.main(new String[] { Spring.class.getName(),
"org/springframework/bootstrap/sample-beans.xml" });
}
}
Loading…
Cancel
Save