diff --git a/build.gradle b/build.gradle index 6a6814a..6dc3d09 100644 --- a/build.gradle +++ b/build.gradle @@ -23,6 +23,7 @@ configurations { } dependencies { + implementation project(':common-logging-starter') implementation 'org.springframework.boot:spring-boot-starter' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' diff --git a/common-logging-starter/build.gradle b/common-logging-starter/build.gradle new file mode 100644 index 0000000..067d4d7 --- /dev/null +++ b/common-logging-starter/build.gradle @@ -0,0 +1,26 @@ +plugins { + id 'java' +} + +group 'com.dmdev' +version '1.0-SNAPSHOT' + +repositories { + mavenCentral() +} + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-aop:2.6.2' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa:2.6.2' + + compileOnly 'org.projectlombok:lombok:1.18.22' + annotationProcessor 'org.projectlombok:lombok:1.18.22' + + annotationProcessor "org.springframework.boot:spring-boot-configuration-processor:2.6.2" + + testImplementation 'org.springframework.boot:spring-boot-starter-test:2.6.2' +} + +test { + useJUnitPlatform() +} \ No newline at end of file diff --git a/src/main/java/com/dmdev/spring/aop/CommonPointcuts.java b/common-logging-starter/src/main/java/com/dmdev/logging/aop/CommonPointcuts.java similarity index 82% rename from src/main/java/com/dmdev/spring/aop/CommonPointcuts.java rename to common-logging-starter/src/main/java/com/dmdev/logging/aop/CommonPointcuts.java index ebd0c6e..1b1091b 100644 --- a/src/main/java/com/dmdev/spring/aop/CommonPointcuts.java +++ b/common-logging-starter/src/main/java/com/dmdev/logging/aop/CommonPointcuts.java @@ -1,11 +1,10 @@ -package com.dmdev.spring.aop; +package com.dmdev.logging.aop; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; @Aspect -@Component public class CommonPointcuts { /* @@ -18,7 +17,7 @@ public void isControllerLayer() { /* within - check class type name */ - @Pointcut("within(com.dmdev.spring.service.*Service)") + @Pointcut("within(com.dmdev.*.service.*Service)") public void isServiceLayer() { } } diff --git a/src/main/java/com/dmdev/spring/aop/FirstAspect.java b/common-logging-starter/src/main/java/com/dmdev/logging/aop/FirstAspect.java similarity index 62% rename from src/main/java/com/dmdev/spring/aop/FirstAspect.java rename to common-logging-starter/src/main/java/com/dmdev/logging/aop/FirstAspect.java index db34d7b..14c59a9 100644 --- a/src/main/java/com/dmdev/spring/aop/FirstAspect.java +++ b/common-logging-starter/src/main/java/com/dmdev/logging/aop/FirstAspect.java @@ -1,4 +1,4 @@ -package com.dmdev.spring.aop; +package com.dmdev.logging.aop; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; @@ -14,55 +14,12 @@ @Slf4j @Aspect -@Component -@Order(1) public class FirstAspect { - /* - this - check AOP proxy class type - target - check target object class type - */ - @Pointcut("this(org.springframework.data.repository.Repository)") -// @Pointcut("target(org.springframework.data.repository.Repository)") - public void isRepositoryLayer() { - } - - /* - @annotation - check annotation on method level - */ - @Pointcut("com.dmdev.spring.aop.CommonPointcuts.isControllerLayer() && @annotation(org.springframework.web.bind.annotation.GetMapping)") - public void hasGetMapping() { - } - - /* - args - check method param type - * - any param type - .. - 0+ any params type - */ - @Pointcut("com.dmdev.spring.aop.CommonPointcuts.isControllerLayer() && args(org.springframework.ui.Model,..)") - public void hasModelParam() { - } - - /* - @args - check annotation on the param type - * - any param type - .. - 0+ any params type - */ - @Pointcut("com.dmdev.spring.aop.CommonPointcuts.isControllerLayer() && @args(com.dmdev.spring.validation.UserInfo,..)") - public void hasUserInfoParamAnnotation() { - } - - /* - bean - check bean name - */ - @Pointcut("bean(*Service)") - public void isServiceLayerBean() { - } - /* execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?) */ - @Pointcut("execution(public * com.dmdev.spring.service.*Service.findById(*))") + @Pointcut("execution(public * com.dmdev.*.service.*Service.findById(*))") public void anyFindByIdServiceMethod() { } diff --git a/src/main/java/com/dmdev/spring/aop/SecondAspect.java b/common-logging-starter/src/main/java/com/dmdev/logging/aop/SecondAspect.java similarity index 87% rename from src/main/java/com/dmdev/spring/aop/SecondAspect.java rename to common-logging-starter/src/main/java/com/dmdev/logging/aop/SecondAspect.java index 94925b8..7bc8050 100644 --- a/src/main/java/com/dmdev/spring/aop/SecondAspect.java +++ b/common-logging-starter/src/main/java/com/dmdev/logging/aop/SecondAspect.java @@ -1,4 +1,4 @@ -package com.dmdev.spring.aop; +package com.dmdev.logging.aop; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; @@ -9,11 +9,9 @@ @Slf4j @Aspect -@Component -@Order(2) public class SecondAspect { - @Around("com.dmdev.spring.aop.FirstAspect.anyFindByIdServiceMethod() && target(service) && args(id)") + @Around("com.dmdev.logging.aop.FirstAspect.anyFindByIdServiceMethod() && target(service) && args(id)") public Object addLoggingAround(ProceedingJoinPoint joinPoint, Object service, Object id) throws Throwable { log.info("AROUND before - invoked findById method in class {}, with id {}", service, id); try { diff --git a/common-logging-starter/src/main/java/com/dmdev/logging/config/LoggingAutoConfiguration.java b/common-logging-starter/src/main/java/com/dmdev/logging/config/LoggingAutoConfiguration.java new file mode 100644 index 0000000..b005e3d --- /dev/null +++ b/common-logging-starter/src/main/java/com/dmdev/logging/config/LoggingAutoConfiguration.java @@ -0,0 +1,56 @@ +package com.dmdev.logging.config; + +import com.dmdev.logging.aop.CommonPointcuts; +import com.dmdev.logging.aop.FirstAspect; +import com.dmdev.logging.aop.SecondAspect; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; + +import javax.annotation.PostConstruct; + +@Slf4j +@Configuration +@EnableConfigurationProperties(LoggingProperties.class) +@ConditionalOnClass(LoggingProperties.class) +@ConditionalOnProperty(prefix = "app.common.logging", name = "enabled", havingValue = "true") +public class LoggingAutoConfiguration { + + @PostConstruct + void init() { + log.info("LoggingAutoConfiguration initialized"); + } + + @Bean + @ConditionalOnMissingBean + public CommonPointcuts commonPointcuts() { + return new CommonPointcuts(); + } + + @Bean + @Order(1) + @ConditionalOnMissingBean + public FirstAspect firstAspect() { + return new FirstAspect(); + } + + @Bean + @Order(2) + @ConditionalOnMissingBean + public SecondAspect secondAspect() { + return new SecondAspect(); + } + + + + + + + + +} diff --git a/common-logging-starter/src/main/java/com/dmdev/logging/config/LoggingProperties.java b/common-logging-starter/src/main/java/com/dmdev/logging/config/LoggingProperties.java new file mode 100644 index 0000000..0c44f8d --- /dev/null +++ b/common-logging-starter/src/main/java/com/dmdev/logging/config/LoggingProperties.java @@ -0,0 +1,25 @@ +package com.dmdev.logging.config; + +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.context.properties.ConfigurationProperties; + +import javax.annotation.PostConstruct; + +@Slf4j +@Data +@NoArgsConstructor +@ConfigurationProperties(prefix = "app.common.logging") +public class LoggingProperties { + /** + * to enable common logging aop on service layer + */ + private boolean enabled; + private String level; + + @PostConstruct + void init() { + log.info("Logging properties initialized: {}", this); + } +} diff --git a/common-logging-starter/src/main/resources/META-INF/spring.factories b/common-logging-starter/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..fd3e12e --- /dev/null +++ b/common-logging-starter/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +com.dmdev.logging.config.LoggingAutoConfiguration \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index b075813..e56ab03 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,4 @@ rootProject.name = 'spring-starter' +include 'common-logging-starter' + diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index bd892aa..168b736 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -21,6 +21,10 @@ db: spring.profiles.active: qa +app.common.logging: + enabled: true + level: INFO + logging: level: root: INFO