Skip to content

Instantly share code, notes, and snippets.

@jbrisbin
Created December 7, 2012 17:00
Show Gist options
  • Save jbrisbin/4234670 to your computer and use it in GitHub Desktop.
Save jbrisbin/4234670 to your computer and use it in GitHub Desktop.
New Spring Data REST JavaConfig
public class RestExporterWebInitializer implements WebApplicationInitializer {
@Override public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext rootCtx = new AnnotationConfigWebApplicationContext();
rootCtx.register(JpaRepositoryConfig.class, MongoDbRepositoryConfig.class);
servletContext.addListener(new ContextLoaderListener(rootCtx));
AnnotationConfigWebApplicationContext webCtx = new AnnotationConfigWebApplicationContext();
webCtx.register(RestExporterExampleRestConfig.class);
DispatcherServlet dispatcherServlet = new DispatcherServlet(webCtx);
ServletRegistration.Dynamic reg = servletContext.addServlet("exporter", dispatcherServlet);
reg.setLoadOnStartup(1);
reg.addMapping("/*");
}
}
@Configuration
@ComponentScan(basePackageClasses = JpaRepositoryConfig.class)
@EnableJpaRepositories
@EnableTransactionManagement
public class JpaRepositoryConfig {
@Bean public DataSource dataSource() {
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
return builder.setType(EmbeddedDatabaseType.HSQL).build();
}
@Bean public EntityManagerFactory entityManagerFactory() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setDatabase(Database.HSQL);
vendorAdapter.setGenerateDdl(true);
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan(getClass().getPackage().getName());
factory.setDataSource(dataSource());
factory.afterPropertiesSet();
return factory.getObject();
}
@Bean public JpaDialect jpaDialect() {
return new HibernateJpaDialect();
}
@Bean public PlatformTransactionManager transactionManager() {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory());
return txManager;
}
}
@Configuration
@ComponentScan(basePackageClasses = MongoDbRepositoryConfig.class)
@EnableMongoRepositories
public class MongoDbRepositoryConfig {
@Bean public MongoDbFactory mongoDbFactory() throws UnknownHostException {
return new SimpleMongoDbFactory(new Mongo("localhost"), "spring-data-rest-example");
}
@Bean public MongoTemplate mongoTemplate() throws UnknownHostException {
return new MongoTemplate(mongoDbFactory());
}
}
@Configuration
public class RestExporterExampleRestConfig extends RepositoryRestMvcConfiguration {
@Autowired
ApplicationContext appCtx;
@Bean public Repositories repositories() {
return new Repositories(appCtx);
}
}
@Configuration
@ImportResource("classpath*:META-INF/spring-data-rest/**/*-export.xml")
public class RepositoryRestMvcConfiguration {
private static final boolean IS_HIBERNATE4_MODULE_AVAILABLE = ClassUtils.isPresent(
"com.fasterxml.jackson.datatype.hibernate4.Hibernate4Module",
RepositoryRestMvcConfiguration.class.getClassLoader()
);
private static final boolean IS_JODA_MODULE_AVAILABLE = ClassUtils.isPresent(
"com.fasterxml.jackson.datatype.joda.JodaModule",
RepositoryRestMvcConfiguration.class.getClassLoader()
);
@Bean public DefaultFormattingConversionService defaultConversionService() {
DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
conversionService.addConverter(UUIDConverter.INSTANCE);
conversionService.addConverter(ISO8601DateConverter.INSTANCE);
configureConversionService(conversionService);
return conversionService;
}
@Bean public DomainClassConverter<?> domainClassConverter() {
return new DomainClassConverter<DefaultFormattingConversionService>(defaultConversionService());
}
/**
* {@link org.springframework.context.ApplicationListener} implementation for invoking {@link
* org.springframework.validation.Validator} instances assigned to specific domain types.
*/
@Bean public ValidatingRepositoryEventListener validatingRepositoryEventListener() {
ValidatingRepositoryEventListener listener = new ValidatingRepositoryEventListener();
configureValidatingRepositoryEventListener(listener);
return listener;
}
/**
* Main configuration for the REST exporter.
*/
@Bean public RepositoryRestConfiguration config() {
RepositoryRestConfiguration config = new RepositoryRestConfiguration();
configureRepositoryRestConfiguration(config);
return config;
}
/**
* For getting access to the {@link javax.persistence.EntityManagerFactory}.
*
* @return
*/
@Bean public PersistenceAnnotationBeanPostProcessor persistenceAnnotationBeanPostProcessor() {
return new PersistenceAnnotationBeanPostProcessor();
}
/**
* {@link org.springframework.beans.factory.config.BeanPostProcessor} to turn beans annotated as {@link
* org.springframework.data.rest.repository.annotation.RepositoryEventHandler}s.
*
* @return
*/
@Bean public AnnotatedHandlerBeanPostProcessor annotatedHandlerBeanPostProcessor() {
return new AnnotatedHandlerBeanPostProcessor();
}
/**
* The main REST exporter Spring MVC controller.
*
* @return
*/
@Bean public RepositoryRestController repositoryRestController() {
RepositoryRestController controller = new RepositoryRestController();
configureRepositoryRestController(controller);
return controller;
}
/**
* Resolves the base {@link java.net.URI} under which this application is configured.
*
* @return
*/
@Bean public BaseUriMethodArgumentResolver baseUriMethodArgumentResolver() {
return new BaseUriMethodArgumentResolver();
}
@Bean public PagingAndSortingMethodArgumentResolver pagingAndSortingMethodArgumentResolver() {
return new PagingAndSortingMethodArgumentResolver();
}
@Bean public ServerHttpRequestMethodArgumentResolver serverHttpRequestMethodArgumentResolver() {
return new ServerHttpRequestMethodArgumentResolver();
}
/**
* Special {@link org.springframework.web.servlet.HandlerAdapter} that only recognizes handler methods defined in
* the
* {@link RepositoryRestController} class.
*
* @return
*/
@Bean public RepositoryRestHandlerAdapter repositoryExporterHandlerAdapter() {
MappingJackson2HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
// Our special PersistentEntityResource Module
objectMapper.registerModule(persistentEntityJackson2Module());
// Hibernate types
if(IS_HIBERNATE4_MODULE_AVAILABLE) {
objectMapper.registerModule(new com.fasterxml.jackson.datatype.hibernate4.Hibernate4Module());
}
// JODA time
if(IS_JODA_MODULE_AVAILABLE) {
objectMapper.registerModule(new com.fasterxml.jackson.datatype.joda.JodaModule());
}
// Configure custom Modules
configureJacksonObjectMapper(objectMapper);
// User our custom ObjectMapper
jacksonConverter.setObjectMapper(objectMapper);
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
messageConverters.add(jacksonConverter);
configureHttpMessageConverters(messageConverters);
HandlerMethodReturnValueHandlerComposite hmrvh = new HandlerMethodReturnValueHandlerComposite();
hmrvh.addHandler(new RequestResponseBodyMethodProcessor(messageConverters));
hmrvh.addHandler(new HttpEntityMethodProcessor(messageConverters));
List<ResourceProcessor<?>> resourceProcessors = new ArrayList<ResourceProcessor<?>>();
configureResourceProcessors(resourceProcessors);
ResourceProcessorHandlerMethodReturnValueHandler rpvh = new ResourceProcessorHandlerMethodReturnValueHandler(
new RequestResponseBodyMethodProcessor(messageConverters),
resourceProcessors
);
RepositoryRestHandlerAdapter handlerAdapter = new RepositoryRestHandlerAdapter();
handlerAdapter.setMessageConverters(messageConverters);
handlerAdapter.setCustomArgumentResolvers(
Arrays.asList(baseUriMethodArgumentResolver(),
pagingAndSortingMethodArgumentResolver(),
serverHttpRequestMethodArgumentResolver())
);
handlerAdapter.setCustomReturnValueHandlers(
Arrays.<HandlerMethodReturnValueHandler>asList(rpvh)
);
return handlerAdapter;
}
/**
* Special {@link org.springframework.web.servlet.HandlerMapping} that only recognizes handler methods defined in
* the
* {@link RepositoryRestController} class.
*
* @return
*/
@Bean public RepositoryRestHandlerMapping repositoryExporterHandlerMapping() {
return new RepositoryRestHandlerMapping();
}
@Bean public PersistentEntityJackson2Module persistentEntityJackson2Module() {
return new PersistentEntityJackson2Module();
}
/**
* Bean for looking up methods annotated with {@link org.springframework.web.bind.annotation.ExceptionHandler}.
*
* @return
*/
@Bean public ExceptionHandlerExceptionResolver exceptionHandlerExceptionResolver() {
ExceptionHandlerExceptionResolver er = new ExceptionHandlerExceptionResolver();
er.setCustomArgumentResolvers(
Arrays.<HandlerMethodArgumentResolver>asList(
serverHttpRequestMethodArgumentResolver(),
baseUriMethodArgumentResolver()
)
);
configureExceptionHandlerExceptionResolver(er);
return er;
}
/**
* Override this method to add additional configuration.
*
* @param config
* Main configuration bean.
*/
protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
}
/**
* Override this method to add your own converters.
*
* @param conversionService
* Default ConversionService bean.
*/
protected void configureConversionService(ConfigurableConversionService conversionService) {
}
/**
* Override this method to add validators manually.
*
* @param validatingListener
* The {@link org.springframework.context.ApplicationListener} responsible for invoking {@link
* org.springframework.validation.Validator} instances.
*/
protected void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) {
}
/**
* Configure the REST controller directly.
*
* @param controller
* The {@link RepositoryRestController} instance.
*/
protected void configureRepositoryRestController(RepositoryRestController controller) {
}
/**
* Configure the {@link ExceptionHandlerExceptionResolver}.
*
* @param exceptionResolver
* The default exception resolver on which you can add custom argument resolvers.
*/
protected void configureExceptionHandlerExceptionResolver(ExceptionHandlerExceptionResolver exceptionResolver) {
}
protected void configureResourceProcessors(List<ResourceProcessor<?>> resourceProcessors) {
}
protected void configureHttpMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
}
protected void configureJacksonObjectMapper(ObjectMapper objectMapper) {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment