Help to developer for spring-boot 2.1.x or higher applications
![Quality Gate Status](https://camo.githubusercontent.com/5af064a098401567ca3f37bca6bf74a69705a9c51dccb9b66fd05d7cc1bb65f6/68747470733a2f2f736f6e6172636c6f75642e696f2f6170692f70726f6a6563745f6261646765732f6d6561737572653f70726f6a6563743d736865726d656e64655f6465762e736865726d656e64652e737570706f72742d737072696e67266d65747269633d616c6572745f737461747573)
![Maven pipeline](https://github.com/shermende/dev.shermende.support-spring/workflows/Maven%20pipeline/badge.svg)
<dependency>
<groupId>dev.shermende</groupId>
<artifactId>support-spring</artifactId>
<version>1.1.2</version>
</dependency>
Other examples here
@Component
public class ExampleFactory extends AbstractFactory<String, Converter<Object, Object>> {
public Factory(BeanFactory beanFactory) {
super(beanFactory);
}
@Override
protected void registration() {
this.registry("one", ExampleConverterOne.class);
this.registry("two", ExampleConverterTwo.class);
}
}
step 2. create factory items
@Component
public class ExampleConverterOne implements Converter<Object, Object> {
@Override
public Object convert(Object o) {
return o;
}
}
@Component
public class ExampleConverterTwo implements Converter<Object, Object> {
@Override
public Object convert(Object o) {
return o;
}
}
@Service
@RequiredArgsConstructor
public class ExampleService {
private final ExampleFactory factory;
public void handle(
Object o
) {
factory.getInstance("one").convert(o);
}
}
Step processor as chain of responsibility
step 1. create step processor
@Component
public class ExampleStepProcessor extends AbstractStepProcessor<Object, Object> {
protected ExampleStepProcessor(BeanFactory factory) {
super(factory);
}
@Override
protected Collection<Class<? extends Step<Object, Object>>> steps() {
return Arrays.asList(ExampleFirstStep.class, ExampleSecondStep.class);
}
}
@Component
public class ExampleFirstStep implements Step<Object, Object> {
@Override
public Object execute(Object o) {
return o;
}
}
@Component
public class ExampleSecondStep implements Step<Object, Object> {
@Override
public Object execute(Object o) {
return o;
}
}
@Service
@RequiredArgsConstructor
public class ExampleService {
private final ExampleStepProcessor processor;
public void handle(
Object o
) {
processor.execute(o);
}
}
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class ApplicationConfiguration {
@Bean
public InterceptAspect interceptAspect() {
return new InterceptAspect();
}
}
step 2. create interceptor
@Component
public class ExampleInterceptor implements Interceptor {
@Override
public boolean supports(
Class<?> aClass
) {
return Object.class.isAssignableFrom(aClass);
}
@Override
public void intercept(
Object o
) {
// processing
}
}
@Service
public class ExampleService {
@Intercept
public void handle(
@InterceptArgument(ExampleInterceptor.class) Object payload
) {
// processing
}
}
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class ProfilingAspectTestConfiguration {
/**
* jmx control. use mbeans for runtime on/off
*/
@Bean
public JmxControl jmxControl() {
return new ToggleJmxControlImpl(true);
}
/**
* enabling profiling aspect
*/
@Bean
public ProfilingAspect interceptAspect(JmxControl jmxControl) {
return new ProfilingAspect(jmxControl);
}
}
@Component
public class ProfilingAspectTestComponent {
@Profiling
public Object convert(
Object payload
) {
return payload;
}
}
[main] DEBUG dev.shermende.support.spring.aop.profiling.ProfilingAspect - [Profiling] [ProfilingAspectTestComponent#convert] [Duration:11]
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class LoggingAspectTestConfiguration {
/**
* jmx control. use mbeans for runtime on/off
*/
@Bean
public JmxControl jmxControl() {
return new ToggleJmxControlImpl(true);
}
/**
* enabling profiling aspect
*/
@Bean
public LoggingAspect interceptAspect(JmxControl jmxControl) {
return new LoggingAspect(jmxControl);
}
}
@Component
public class LoggingAspectTestComponent {
@Logging
public Object convert(
Object payload
) {
return payload;
}
}
[main] DEBUG dev.shermende.support.spring.aop.logging.LoggingAspect - [Logging before] [LoggingAspectTestComponent#convert] [Args:[java.lang.Object@bcec031]]
[main] DEBUG dev.shermende.support.spring.aop.logging.LoggingAspect - [Logging after] [LoggingAspectTestComponent#convert] [Args:[java.lang.Object@bcec031]] [Result:java.lang.Object@bcec031]
JMH Benchmarking results on GithubActions pipeline
# JMH version: 1.26
# VM version: JDK 1.8.0_275, OpenJDK 64-Bit Server VM, 25.275-b01
# VM invoker: /opt/hostedtoolcache/jdk/8.0.275/x64/jre/bin/java
# VM options: <none>
# Warmup: 3 iterations, 10 s each
# Measurement: 3 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 10 threads, will synchronize iterations
# Benchmark mode: Average time, time/op
Benchmark Mode Cnt Score Error Units
AbstractFactoryTestBenchmark.benchmark avgt 3 0.797 ± 0.183 us/op
AbstractStepProcessorBenchmark.benchmark avgt 3 1.098 ± 0.266 us/op
DirectInvocationBenchmark.benchmark avgt 3 0.350 ± 0.105 us/op
EmptyAspectBenchmark.benchmark avgt 3 0.398 ± 0.045 us/op
InterceptAspectBenchmark.benchmark avgt 3 40.699 ± 5.868 us/op
InterceptResultAspectBenchmark.benchmark avgt 3 3.942 ± 0.641 us/op
LoggingAspectBenchmark.benchmark avgt 3 5.864 ± 1.611 us/op
LoggingAspectDisabledBenchmark.benchmark avgt 3 2.466 ± 0.437 us/op
ProfilingAspectBenchmark.benchmark avgt 3 4.983 ± 0.407 us/op
ProfilingAspectDisabledBenchmark.benchmark avgt 3 2.430 ± 0.667 us/op
java.lang.ClassNotFoundException: org.aspectj.lang.annotation.Pointcut
Cure. Add spring-boot-starter-aop
to project
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>