diff --git a/README.md b/README.md
index d0a4f392..e07bec84 100644
--- a/README.md
+++ b/README.md
@@ -1374,6 +1374,15 @@ Specification argument resolver is available in the Maven Central:
```
+Also, there is an autoconfiguration starter you can use:
+```xml
+
+ net.kaczmarzyk
+ sar-spring-boot-starter
+ 1.0.0
+
+```
+
If a new version is not yet available in the central repository (or you need a SNAPSHOT version), you can grab it from my private repo:
```xml
diff --git a/sar-spring-boot-starter/pom.xml b/sar-spring-boot-starter/pom.xml
new file mode 100644
index 00000000..af238f99
--- /dev/null
+++ b/sar-spring-boot-starter/pom.xml
@@ -0,0 +1,235 @@
+
+
+ 4.0.0
+
+ net.kaczmarzyk
+ sar-spring-boot-starter
+ 1.0.0-SNAPSHOT
+ pom
+ 2014
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ 3.0.2
+ pom
+ import
+
+
+
+
+
+
+ net.kaczmarzyk
+ specification-arg-resolver
+ 3.0.2-SNAPSHOT
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure
+
+
+ org.springdoc
+ springdoc-openapi-starter-common
+ 2.0.2
+ true
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ junit
+ junit
+ test
+
+
+ org.assertj
+ assertj-core
+ test
+
+
+ org.springframework
+ spring-test
+ test
+
+
+
+
+ 17
+ 17
+
+
+
+ scm:git:https://github.com/tkaczmarzyk/specification-arg-resolver.git
+ scm:git:https://github.com/tkaczmarzyk/specification-arg-resolver.git
+ scm:git:https://github.com/tkaczmarzyk/specification-arg-resolver.git
+ HEAD
+
+
+
+
+ sonatype
+
+ false
+
+
+
+ nexus-releases
+ Nexus Release Repository
+ https://oss.sonatype.org/service/local/staging/deploy/maven2/
+
+
+ nexus-snapshots
+ Nexus Snapshot Repository
+ https://oss.sonatype.org/content/repositories/snapshots/
+
+
+
+
+ sign
+
+ false
+
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ 3.0.1
+
+
+ sign-artifacts
+ verify
+
+ sign
+
+
+
+
+
+
+
+
+
+
+
+
+ maven-compiler-plugin
+ 3.10.1
+
+ 17
+ 17
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.0.0-M8
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 3.2.1
+
+
+ attach-sources
+
+ jar
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.4.1
+
+
+ attach-javadocs
+
+ jar
+
+
+
+
+
+ com.mycila.maven-license-plugin
+ maven-license-plugin
+ 1.10.b1
+
+ src/etc/license_header.txt
+ false
+ true
+ false
+
+ src/main/java/**
+ src/test/java/**
+
+
+ src/site
+
+ true
+ true
+
+ ${project.inceptionYear}-2023
+
+ UTF-8
+
+
+
+ test
+
+ check
+
+
+
+
+
+ maven-release-plugin
+ 2.5.3
+
+ v@{project.version}
+
+
+
+ org.apache.maven.scm
+ maven-scm-provider-gitexe
+ 1.13.0
+
+
+ org.apache.maven.scm
+ maven-scm-api
+ 1.13.0
+
+
+
+
+
+
+ org.apache.maven.wagon
+ wagon-ftp
+ 3.5.3
+
+
+
+
+
+
+ kaczmarzyk.net
+ kaczmarzyk.net repository
+ ftp://repo.kaczmarzyk.net
+
+
+ kaczmarzyk.net
+ kaczmarzyk.net repository
+ ftp://repo.kaczmarzyk.net
+
+
+
\ No newline at end of file
diff --git a/sar-spring-boot-starter/src/etc/license_header.txt b/sar-spring-boot-starter/src/etc/license_header.txt
new file mode 100644
index 00000000..deb6adcc
--- /dev/null
+++ b/sar-spring-boot-starter/src/etc/license_header.txt
@@ -0,0 +1,13 @@
+Copyright ${year} 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.
diff --git a/sar-spring-boot-starter/src/main/java/net/kaczmarzyk/autoconfiguration/SpecificationArgumentResolverAutoConfiguration.java b/sar-spring-boot-starter/src/main/java/net/kaczmarzyk/autoconfiguration/SpecificationArgumentResolverAutoConfiguration.java
new file mode 100644
index 00000000..f6772f0e
--- /dev/null
+++ b/sar-spring-boot-starter/src/main/java/net/kaczmarzyk/autoconfiguration/SpecificationArgumentResolverAutoConfiguration.java
@@ -0,0 +1,58 @@
+/**
+ * Copyright 2014-2023 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 net.kaczmarzyk.autoconfiguration;
+
+import net.kaczmarzyk.spring.data.jpa.swagger.springdoc.SpecificationArgResolverSpringdocOperationCustomizer;
+import net.kaczmarzyk.spring.data.jpa.web.SpecificationArgumentResolver;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.support.AbstractApplicationContext;
+import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
+
+import java.util.Locale;
+
+@AutoConfiguration
+public class SpecificationArgumentResolverAutoConfiguration {
+
+ @Autowired
+ AbstractApplicationContext applicationContext;
+
+ @Value(value = "${specification-arg-resolver.locale:EN}")
+ String locale;
+
+ @ConditionalOnMissingBean
+ @Bean
+ public SpecificationArgumentResolver defaultSpecificationArgumentResolver() {
+ return new SpecificationArgumentResolver(applicationContext, Locale.forLanguageTag(locale));
+ }
+
+ @ConditionalOnMissingBean
+ @Bean
+ public PageableHandlerMethodArgumentResolver defaultPageableHandlerMethodArgumentResolver() {
+ return new PageableHandlerMethodArgumentResolver();
+ }
+
+ @ConditionalOnMissingBean
+ @ConditionalOnProperty(prefix = "specification-arg-resolver", name = "spring-doc-operation-customizer", havingValue = "true")
+ @Bean
+ public SpecificationArgResolverSpringdocOperationCustomizer defaultSpecificationArgResolverSpringdocOperationCustomizer() {
+ return new SpecificationArgResolverSpringdocOperationCustomizer();
+ }
+}
diff --git a/sar-spring-boot-starter/src/main/java/net/kaczmarzyk/autoconfiguration/SpecificationArgumentResolverWebMvcConfigurer.java b/sar-spring-boot-starter/src/main/java/net/kaczmarzyk/autoconfiguration/SpecificationArgumentResolverWebMvcConfigurer.java
new file mode 100644
index 00000000..4de215a4
--- /dev/null
+++ b/sar-spring-boot-starter/src/main/java/net/kaczmarzyk/autoconfiguration/SpecificationArgumentResolverWebMvcConfigurer.java
@@ -0,0 +1,41 @@
+/**
+ * Copyright 2014-2023 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 net.kaczmarzyk.autoconfiguration;
+
+import net.kaczmarzyk.spring.data.jpa.web.SpecificationArgumentResolver;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
+import org.springframework.web.method.support.HandlerMethodArgumentResolver;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import java.util.List;
+
+@AutoConfiguration
+public class SpecificationArgumentResolverWebMvcConfigurer implements WebMvcConfigurer {
+
+ @Autowired
+ SpecificationArgumentResolver specificationArgumentResolver;
+
+ @Autowired
+ PageableHandlerMethodArgumentResolver pageableHandlerMethodArgumentResolver;
+
+ @Override
+ public void addArgumentResolvers(List argumentResolvers) {
+ argumentResolvers.add(specificationArgumentResolver);
+ argumentResolvers.add(pageableHandlerMethodArgumentResolver);
+ }
+}
diff --git a/sar-spring-boot-starter/src/test/java/net/kaczmarzyk/autoconfiguration/SarTestConfiguration.java b/sar-spring-boot-starter/src/test/java/net/kaczmarzyk/autoconfiguration/SarTestConfiguration.java
new file mode 100644
index 00000000..1621a43e
--- /dev/null
+++ b/sar-spring-boot-starter/src/test/java/net/kaczmarzyk/autoconfiguration/SarTestConfiguration.java
@@ -0,0 +1,26 @@
+package net.kaczmarzyk.autoconfiguration;
+
+import net.kaczmarzyk.spring.data.jpa.swagger.springdoc.SpecificationArgResolverSpringdocOperationCustomizer;
+import net.kaczmarzyk.spring.data.jpa.web.SpecificationArgumentResolver;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
+
+@Configuration
+public class SarTestConfiguration {
+
+ @Bean
+ public SpecificationArgumentResolver differentSpecificationArgumentResolver() {
+ return new SpecificationArgumentResolver();
+ }
+
+ @Bean
+ public PageableHandlerMethodArgumentResolver differentPageableHandlerMethodArgumentResolver() {
+ return new PageableHandlerMethodArgumentResolver();
+ }
+
+ @Bean
+ public SpecificationArgResolverSpringdocOperationCustomizer differentSpecificationArgResolverSpringdocOperationCustomizer() {
+ return new SpecificationArgResolverSpringdocOperationCustomizer();
+ }
+}
diff --git a/sar-spring-boot-starter/src/test/java/net/kaczmarzyk/autoconfiguration/SpecificationArgumentResolverAutoConfigurationTest.java b/sar-spring-boot-starter/src/test/java/net/kaczmarzyk/autoconfiguration/SpecificationArgumentResolverAutoConfigurationTest.java
new file mode 100644
index 00000000..15e6430f
--- /dev/null
+++ b/sar-spring-boot-starter/src/test/java/net/kaczmarzyk/autoconfiguration/SpecificationArgumentResolverAutoConfigurationTest.java
@@ -0,0 +1,79 @@
+/**
+ * Copyright 2014-2023 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 net.kaczmarzyk.autoconfiguration;
+
+import net.kaczmarzyk.spring.data.jpa.swagger.springdoc.SpecificationArgResolverSpringdocOperationCustomizer;
+import net.kaczmarzyk.spring.data.jpa.web.SpecificationArgumentResolver;
+import org.junit.Test;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class SpecificationArgumentResolverAutoConfigurationTest {
+
+ private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();
+
+ @Test
+ public void contextContainsDefaultBeansIfThereAreNotAnyOther() {
+ this.contextRunner
+ .withUserConfiguration(SpecificationArgumentResolverAutoConfiguration.class)
+ .run(context -> {
+ assertThat(context).hasSingleBean(SpecificationArgumentResolver.class);
+ assertThat(context).hasBean("defaultSpecificationArgumentResolver");
+
+ assertThat(context).hasSingleBean(PageableHandlerMethodArgumentResolver.class);
+ assertThat(context).hasBean("defaultPageableHandlerMethodArgumentResolver");
+ });
+ }
+
+ @Test
+ public void contextContainsBeanForSpringdocOperationCustomizationWhenPropertyIsSet() {
+ this.contextRunner
+ .withPropertyValues("specification-arg-resolver.spring-doc-operation-customizer=true")
+ .withUserConfiguration(SpecificationArgumentResolverAutoConfiguration.class)
+ .run(context -> {
+ assertThat(context).hasSingleBean(SpecificationArgResolverSpringdocOperationCustomizer.class);
+ assertThat(context).hasBean("defaultSpecificationArgResolverSpringdocOperationCustomizer");
+ });
+ }
+
+ @Test
+ public void contextDoesNotContainsBeanForSpringdocOperationCustomizationWhenPropertyIsNotSet() {
+ this.contextRunner
+ .withUserConfiguration(SpecificationArgumentResolverAutoConfiguration.class)
+ .run(context -> {
+ assertThat(context).doesNotHaveBean(SpecificationArgResolverSpringdocOperationCustomizer.class);
+ });
+ }
+
+ @Test
+ public void contextDoesNotContainsDefaultBeansIfThereAreOtherDeclared() {
+ this.contextRunner
+ .withPropertyValues("specification-arg-resolver.spring-doc-operation-customizer=true")
+ .withUserConfiguration(SarTestConfiguration.class, SpecificationArgumentResolverAutoConfiguration.class)
+ .run(context -> {
+ assertThat(context).hasSingleBean(SpecificationArgumentResolver.class);
+ assertThat(context).hasBean("differentSpecificationArgumentResolver");
+
+ assertThat(context).hasSingleBean(PageableHandlerMethodArgumentResolver.class);
+ assertThat(context).hasBean("differentPageableHandlerMethodArgumentResolver");
+
+ assertThat(context).hasSingleBean(SpecificationArgResolverSpringdocOperationCustomizer.class);
+ assertThat(context).hasBean("differentSpecificationArgResolverSpringdocOperationCustomizer");
+ });
+ }
+}