diff --git a/tesler-core/src/main/java/io/tesler/core/autoconfigure/AutoConfiguration.java b/tesler-core/src/main/java/io/tesler/core/autoconfigure/AutoConfiguration.java
new file mode 100644
index 0000000000..c5efc143c5
--- /dev/null
+++ b/tesler-core/src/main/java/io/tesler/core/autoconfigure/AutoConfiguration.java
@@ -0,0 +1,43 @@
+/*-
+ * #%L
+ * IO Tesler - Core
+ * %%
+ * Copyright (C) 2018 - 2019 Tesler Contributors
+ * %%
+ * 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.
+ * #L%
+ */
+
+package io.tesler.core.autoconfigure;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.AliasFor;
+
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Configuration
+public @interface AutoConfiguration {
+
+ @AliasFor(annotation = Configuration.class, attribute = "proxyBeanMethods")
+ boolean proxyBeanMethods() default true;
+
+ @AliasFor(annotation = Configuration.class, attribute = "proxyBeanMethods")
+ String value() default "";
+
+}
diff --git a/tesler-core/src/main/java/io/tesler/core/config/cache/TeslerCacheAutoConfiguration.java b/tesler-core/src/main/java/io/tesler/core/autoconfigure/cache/TeslerCacheAutoConfiguration.java
similarity index 73%
rename from tesler-core/src/main/java/io/tesler/core/config/cache/TeslerCacheAutoConfiguration.java
rename to tesler-core/src/main/java/io/tesler/core/autoconfigure/cache/TeslerCacheAutoConfiguration.java
index de0ededcd1..eb7d0e98ed 100644
--- a/tesler-core/src/main/java/io/tesler/core/config/cache/TeslerCacheAutoConfiguration.java
+++ b/tesler-core/src/main/java/io/tesler/core/autoconfigure/cache/TeslerCacheAutoConfiguration.java
@@ -18,11 +18,20 @@
* #L%
*/
-package io.tesler.core.config.cache;
-
+package io.tesler.core.autoconfigure.cache;
+
+import com.google.common.collect.ImmutableList;
+import io.tesler.core.autoconfigure.AutoConfiguration;
+import io.tesler.core.config.cache.CacheConfig;
+import io.tesler.core.config.cache.CacheManagerBasedCacheResolver;
+import io.tesler.core.config.cache.TeslerCaches;
+import io.tesler.core.config.cache.TeslerRequestAwareCacheHolder;
import io.tesler.core.metahotreload.MetaHotReloadService;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+import javax.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
-import org.jetbrains.annotations.NotNull;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
@@ -42,16 +51,22 @@
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.annotation.RequestScope;
import org.springframework.web.context.request.RequestContextHolder;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.stream.Collectors;
-@Configuration
+/**
+ *
Auto-configuration class which declares "teslerCacheResolver" bean of type CacheResolver.
+ * As it says in the Spring documentation:
+ * Auto-configuration is non-invasive. At any point, you can start to define your own configuration to replace specific parts of the auto-configuration.
+ * It follows that if you declare a bean with name "teslerCacheResolver" and type {@link CacheResolver CacheResolver} in a project, which defines dependency on Tesler, this autoconfiguration will be ignored, otherwise it will create the "teslerCacheResolver" bean {@link #teslerCacheResolver defined below}.
+ * A bean named "teslerCacheResolver" is used by Tesler in all annotations which are related to Spring cache abstraction.
+ * {@link AutoConfiguration @AutoConfiguration} is nothing but alias for {@link org.springframework.context.annotation.Configuration @Configuration},
+ * it is used to exclude a class from component scanning (see {@link io.tesler.core.config.BeanScan @BeanScan}).
+ *
+ * @see CacheManagerBasedCacheResolver
+ */
+@AutoConfiguration
@ConditionalOnClass({CacheManager.class})
@ConditionalOnMissingBean(name = "teslerCacheResolver")
@ConditionalOnBean({CacheAspectSupport.class})
@@ -67,17 +82,12 @@ public class TeslerCacheAutoConfiguration {
public CacheResolver teslerCacheResolver(MetaHotReloadService metaHotReloadService) {
metaHotReloadService.loadMeta();
if (CacheType.NONE.equals(cacheProperties.getType())) {
- return new TeslerCacheResolver(new NoOpCacheManager());
+ return new CacheManagerBasedCacheResolver(new NoOpCacheManager());
}
CompositeCacheManager compositeCacheManager = new CompositeCacheManager();
compositeCacheManager.setCacheManagers(buildCacheManagers());
compositeCacheManager.setFallbackToNoOpCache(true);
- return new TeslerCacheResolver(compositeCacheManager);
- }
-
- @Bean
- public TeslerRequestAwareCacheHolder userCache() {
- return new TeslerRequestAwareCacheHolder(new ConcurrentMapCache(CacheConfig.USER_CACHE));
+ return new CacheManagerBasedCacheResolver(compositeCacheManager);
}
@Bean
@@ -86,13 +96,12 @@ public TeslerRequestAwareCacheHolder requestCache() {
return new TeslerRequestAwareCacheHolder(new ConcurrentMapCache(CacheConfig.REQUEST_CACHE));
}
-
protected List buildCacheManagers() {
List result = new ArrayList<>();
result.add(buildUnExpirableCacheManager(
TeslerCaches.getSimpleCacheNames().toArray(new String[0])
));
- result.add(buildRequestAwareCacheManager(TeslerCaches.getRequestCaches()));
+ result.add(buildRequestAwareCacheManager(TeslerCaches.getRequestCacheName()));
return result;
}
@@ -100,11 +109,10 @@ protected CacheManager buildUnExpirableCacheManager(String... names) {
return new ConcurrentMapCacheManager(names);
}
- protected CacheManager buildRequestAwareCacheManager(List cacheNames) {
+ protected CacheManager buildRequestAwareCacheManager(String cacheName) {
SimpleCacheManager simpleCacheManager = new SimpleCacheManager();
- simpleCacheManager.setCaches(cacheNames.stream()
- .map(RequestAwareCacheDecorator::new)
- .collect(Collectors.toList())
+ simpleCacheManager.setCaches(
+ ImmutableList.of(new RequestAwareCacheDecorator(cacheName))
);
simpleCacheManager.initializeCaches();
return simpleCacheManager;
diff --git a/tesler-core/src/main/java/io/tesler/core/config/BeanScan.java b/tesler-core/src/main/java/io/tesler/core/config/BeanScan.java
index 69c027a306..e8c67f153e 100644
--- a/tesler-core/src/main/java/io/tesler/core/config/BeanScan.java
+++ b/tesler-core/src/main/java/io/tesler/core/config/BeanScan.java
@@ -21,6 +21,7 @@
package io.tesler.core.config;
import io.tesler.api.util.spring.ServiceBasedComponentExcludeFilter;
+import io.tesler.core.autoconfigure.AutoConfiguration;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -45,6 +46,7 @@
@Filter(value = {Aspect.class}, type = FilterType.ANNOTATION)
},
excludeFilters = {
+ @Filter(value = {AutoConfiguration.class}, type = FilterType.ANNOTATION),
@Filter(value = {Controller.class, ControllerAdvice.class}, type = FilterType.ANNOTATION),
@Filter(value = {
WebMvcConfigurer.class,
diff --git a/tesler-core/src/main/java/io/tesler/core/config/CoreApplicationConfig.java b/tesler-core/src/main/java/io/tesler/core/config/CoreApplicationConfig.java
index abce3342f0..5cb761bcb1 100644
--- a/tesler-core/src/main/java/io/tesler/core/config/CoreApplicationConfig.java
+++ b/tesler-core/src/main/java/io/tesler/core/config/CoreApplicationConfig.java
@@ -29,18 +29,18 @@
import io.tesler.model.core.dao.JpaDao;
import io.tesler.model.core.service.BaseEntityListenerDelegate;
import io.tesler.model.core.service.TeslerBaseEntityListenerDelegate;
-import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
+import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.aspectj.EnableSpringConfigured;
@EnableAspectJAutoProxy
@BeanScan({"io.tesler"})
@EnableSpringConfigured
-@ImportAutoConfiguration({
+@Import({
MetaHotReloadConfiguration.class,
TeslerFileConfiguration.class
})
@@ -58,4 +58,5 @@ public ResponsibilitiesService responsibilitiesService(JpaDao jpaDao) {
public BaseEntityListenerDelegate baseEntityListenerDelegate(CurrentUserAware currentUserAware) {
return new TeslerBaseEntityListenerDelegate(currentUserAware);
}
+
}
diff --git a/tesler-core/src/main/java/io/tesler/core/config/cache/TeslerCacheResolver.java b/tesler-core/src/main/java/io/tesler/core/config/cache/CacheManagerBasedCacheResolver.java
similarity index 93%
rename from tesler-core/src/main/java/io/tesler/core/config/cache/TeslerCacheResolver.java
rename to tesler-core/src/main/java/io/tesler/core/config/cache/CacheManagerBasedCacheResolver.java
index 9ec03aef8a..90891d5579 100644
--- a/tesler-core/src/main/java/io/tesler/core/config/cache/TeslerCacheResolver.java
+++ b/tesler-core/src/main/java/io/tesler/core/config/cache/CacheManagerBasedCacheResolver.java
@@ -25,9 +25,9 @@
import java.util.Collections;
import java.util.List;
import java.util.Set;
+import javax.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.jetbrains.annotations.NotNull;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.interceptor.CacheOperationInvocationContext;
@@ -35,7 +35,7 @@
@Slf4j
@RequiredArgsConstructor
-public class TeslerCacheResolver implements CacheResolver {
+public class CacheManagerBasedCacheResolver implements CacheResolver {
private final CacheManager teslerCachesManager;
diff --git a/tesler-core/src/main/java/io/tesler/core/config/cache/TeslerCaches.java b/tesler-core/src/main/java/io/tesler/core/config/cache/TeslerCaches.java
index d60e4f1079..f205bc551f 100644
--- a/tesler-core/src/main/java/io/tesler/core/config/cache/TeslerCaches.java
+++ b/tesler-core/src/main/java/io/tesler/core/config/cache/TeslerCaches.java
@@ -20,13 +20,11 @@
package io.tesler.core.config.cache;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import lombok.experimental.UtilityClass;
-
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
+import lombok.Getter;
+import lombok.experimental.UtilityClass;
@UtilityClass
public class TeslerCaches {
@@ -38,24 +36,30 @@ public static List getSimpleCacheNames() {
.collect(Collectors.toList());
}
- public static List getRequestCaches() {
- return Arrays.stream(Caches.values())
- .filter(Caches::isRequestScope)
- .map(Caches::name)
- .collect(Collectors.toList());
+ public static String getRequestCacheName() {
+ return Caches.requestCache.name();
}
- @AllArgsConstructor
+
@Getter
public enum Caches {
- linkedDictionaryRules(false),
- specifications(false),
- widgetcache(false),
- notificationSettings(false),
- workflow(false),
+ linkedDictionaryRules,
+ specifications,
+ widgetcache,
+ notificationSettings,
+ workflow,
requestCache(true),
- userCache(true);
+ userCache;
private final boolean requestScope;
+
+ Caches(boolean requestScope) {
+ this.requestScope = requestScope;
+ }
+
+ Caches() {
+ this.requestScope = false;
+ }
}
+
}
diff --git a/tesler-core/src/main/java/io/tesler/core/file/service/TeslerFileServiceSimple.java b/tesler-core/src/main/java/io/tesler/core/file/service/TeslerFileServiceSimple.java
index e6a4bcc655..cc580d03f8 100644
--- a/tesler-core/src/main/java/io/tesler/core/file/service/TeslerFileServiceSimple.java
+++ b/tesler-core/src/main/java/io/tesler/core/file/service/TeslerFileServiceSimple.java
@@ -25,10 +25,10 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;
+import javax.annotation.Nullable;
import lombok.NonNull;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
-import org.jetbrains.annotations.Nullable;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
diff --git a/tesler-core/src/main/resources/META-INF/spring.factories b/tesler-core/src/main/resources/META-INF/spring.factories
index 192c4c7cff..60d5cc1533 100644
--- a/tesler-core/src/main/resources/META-INF/spring.factories
+++ b/tesler-core/src/main/resources/META-INF/spring.factories
@@ -1,2 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-io.tesler.core.config.cache.TeslerCacheAutoConfiguration
\ No newline at end of file
+io.tesler.core.autoconfigure.cache.TeslerCacheAutoConfiguration
\ No newline at end of file