diff --git a/spring-core-5/pom.xml b/spring-core-5/pom.xml index 743002c137..c404a5cfdb 100644 --- a/spring-core-5/pom.xml +++ b/spring-core-5/pom.xml @@ -25,6 +25,11 @@ ${spring-boot-starter.version} test + + org.projectlombok + lombok + ${lombok.version} + diff --git a/spring-core-5/src/main/java/com/baeldung/component/autoproxying/DataCache.java b/spring-core-5/src/main/java/com/baeldung/component/autoproxying/DataCache.java new file mode 100644 index 0000000000..bc92d0a1d9 --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/component/autoproxying/DataCache.java @@ -0,0 +1,12 @@ +package com.baeldung.component.autoproxying; + +import lombok.Getter; +import org.springframework.stereotype.Component; + +@Getter +@Component +public class DataCache { + @RandomInt(min = 2, max = 10) + private int group; + private String name; +} diff --git a/spring-core-5/src/main/java/com/baeldung/component/autoproxying/EligibleForAutoProxyRandomIntProcessor.java b/spring-core-5/src/main/java/com/baeldung/component/autoproxying/EligibleForAutoProxyRandomIntProcessor.java new file mode 100644 index 0000000000..1fa9aa376f --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/component/autoproxying/EligibleForAutoProxyRandomIntProcessor.java @@ -0,0 +1,33 @@ +package com.baeldung.component.autoproxying; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.context.annotation.Lazy; +import org.springframework.util.ReflectionUtils; + +import java.lang.reflect.Field; + +public class EligibleForAutoProxyRandomIntProcessor implements BeanPostProcessor { + private final RandomIntGenerator randomIntGenerator; + + @Lazy + public EligibleForAutoProxyRandomIntProcessor(RandomIntGenerator randomIntGenerator) { + this.randomIntGenerator = randomIntGenerator; + } + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + Field[] fields = bean.getClass().getDeclaredFields(); + for (Field field : fields) { + RandomInt injectRandomInt = field.getAnnotation(RandomInt.class); + if (injectRandomInt != null) { + int min = injectRandomInt.min(); + int max = injectRandomInt.max(); + int randomValue = randomIntGenerator.generate(min, max); + field.setAccessible(true); + ReflectionUtils.setField(field, bean, randomValue); + } + } + return bean; + } +} diff --git a/spring-core-5/src/main/java/com/baeldung/component/autoproxying/NotEligibleForAutoProxyRandomIntProcessor.java b/spring-core-5/src/main/java/com/baeldung/component/autoproxying/NotEligibleForAutoProxyRandomIntProcessor.java new file mode 100644 index 0000000000..d02780011c --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/component/autoproxying/NotEligibleForAutoProxyRandomIntProcessor.java @@ -0,0 +1,31 @@ +package com.baeldung.component.autoproxying; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.util.ReflectionUtils; + +import java.lang.reflect.Field; + +public class NotEligibleForAutoProxyRandomIntProcessor implements BeanPostProcessor { + private final RandomIntGenerator randomIntGenerator; + + public NotEligibleForAutoProxyRandomIntProcessor(RandomIntGenerator randomIntGenerator) { + this.randomIntGenerator = randomIntGenerator; + } + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + Field[] fields = bean.getClass().getDeclaredFields(); + for (Field field : fields) { + RandomInt injectRandomInt = field.getAnnotation(RandomInt.class); + if (injectRandomInt != null) { + int min = injectRandomInt.min(); + int max = injectRandomInt.max(); + int randomValue = randomIntGenerator.generate(min, max); + field.setAccessible(true); + ReflectionUtils.setField(field, bean, randomValue); + } + } + return bean; + } +} diff --git a/spring-core-5/src/main/java/com/baeldung/component/autoproxying/RandomInt.java b/spring-core-5/src/main/java/com/baeldung/component/autoproxying/RandomInt.java new file mode 100644 index 0000000000..c7881af4af --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/component/autoproxying/RandomInt.java @@ -0,0 +1,11 @@ +package com.baeldung.component.autoproxying; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface RandomInt { + int min(); + + int max(); +} diff --git a/spring-core-5/src/main/java/com/baeldung/component/autoproxying/RandomIntGenerator.java b/spring-core-5/src/main/java/com/baeldung/component/autoproxying/RandomIntGenerator.java new file mode 100644 index 0000000000..d0d44c3333 --- /dev/null +++ b/spring-core-5/src/main/java/com/baeldung/component/autoproxying/RandomIntGenerator.java @@ -0,0 +1,21 @@ +package com.baeldung.component.autoproxying; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.Random; + +@Slf4j +@Component +public class RandomIntGenerator { + private final Random random = new Random(); + private final DataCache dataCache; + + public RandomIntGenerator(DataCache dataCache) { + this.dataCache = dataCache; + } + + public int generate(int min, int max) { + return random.nextInt(max - min) + min; + } +} diff --git a/spring-core-5/src/test/java/com/baeldung/component/autoproxying/EligibleForAutoProxyingIntegrationTest.java b/spring-core-5/src/test/java/com/baeldung/component/autoproxying/EligibleForAutoProxyingIntegrationTest.java new file mode 100644 index 0000000000..4af700813a --- /dev/null +++ b/spring-core-5/src/test/java/com/baeldung/component/autoproxying/EligibleForAutoProxyingIntegrationTest.java @@ -0,0 +1,49 @@ +package com.baeldung.component.autoproxying; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.spi.ILoggingEvent; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = {EligibleForAutoProxyRandomIntProcessor.class, DataCache.class, RandomIntGenerator.class}) +public class EligibleForAutoProxyingIntegrationTest { + private static MemoryLogAppender memoryAppender; + + private EligibleForAutoProxyRandomIntProcessor randomIntProcessor; + + @Autowired + private DataCache dataCache; + + @BeforeClass + public static void setup() { + memoryAppender = new MemoryLogAppender(); + memoryAppender.setContext((LoggerContext) LoggerFactory.getILoggerFactory()); + + Logger logger = (Logger) LoggerFactory.getLogger("org.springframework.context"); + logger.setLevel(Level.INFO); + logger.addAppender(memoryAppender); + memoryAppender.start(); + } + + @Test + public void givenAutowireInBeanPostProcessor_whenSpringContextInitialize_thenNotEligibleLogShouldShowAndGroupFieldPopulated() { + List notEligibleEvents = memoryAppender.search("Bean 'randomIntGenerator' of type [com.baeldung.autoproxying.RandomIntGenerator] " + + "is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)"); + + assertEquals(0, notEligibleEvents.size()); + assertNotEquals(0, dataCache.getGroup()); + } +} diff --git a/spring-core-5/src/test/java/com/baeldung/component/autoproxying/MemoryLogAppender.java b/spring-core-5/src/test/java/com/baeldung/component/autoproxying/MemoryLogAppender.java new file mode 100644 index 0000000000..fad35a7c2b --- /dev/null +++ b/spring-core-5/src/test/java/com/baeldung/component/autoproxying/MemoryLogAppender.java @@ -0,0 +1,48 @@ +package com.baeldung.component.autoproxying; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.read.ListAppender; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +public class MemoryLogAppender extends ListAppender { + public void reset() { + this.list.clear(); + } + + public boolean contains(String string, Level level) { + return this.list.stream() + .anyMatch(event -> event.getMessage().toString().contains(string) + && event.getLevel().equals(level)); + } + + public int countEventsForLogger(String loggerName) { + return (int) this.list.stream() + .filter(event -> event.getLoggerName().contains(loggerName)) + .count(); + } + + public List search(String string) { + return this.list.stream() + .filter(event -> event.getMessage().toString().contains(string)) + .collect(Collectors.toList()); + } + + public List search(String string, Level level) { + return this.list.stream() + .filter(event -> event.getMessage().toString().contains(string) + && event.getLevel().equals(level)) + .collect(Collectors.toList()); + } + + public int getSize() { + return this.list.size(); + } + + public List getLoggedEvents() { + return Collections.unmodifiableList(this.list); + } +} diff --git a/spring-core-5/src/test/java/com/baeldung/component/autoproxying/NotEligibleForAutoProxyingIntegrationTest.java b/spring-core-5/src/test/java/com/baeldung/component/autoproxying/NotEligibleForAutoProxyingIntegrationTest.java new file mode 100644 index 0000000000..9434f77a30 --- /dev/null +++ b/spring-core-5/src/test/java/com/baeldung/component/autoproxying/NotEligibleForAutoProxyingIntegrationTest.java @@ -0,0 +1,48 @@ +package com.baeldung.component.autoproxying; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.spi.ILoggingEvent; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.util.List; + +import static org.junit.Assert.assertEquals; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = {NotEligibleForAutoProxyRandomIntProcessor.class, DataCache.class, RandomIntGenerator.class}) +public class NotEligibleForAutoProxyingIntegrationTest { + private static MemoryLogAppender memoryAppender; + + private NotEligibleForAutoProxyRandomIntProcessor proxyRandomIntProcessor; + + @Autowired + private DataCache dataCache; + + @BeforeClass + public static void setup() { + memoryAppender = new MemoryLogAppender(); + memoryAppender.setContext((LoggerContext) LoggerFactory.getILoggerFactory()); + + Logger logger = (Logger) LoggerFactory.getLogger("org.springframework.context"); + logger.setLevel(Level.INFO); + logger.addAppender(memoryAppender); + memoryAppender.start(); + } + + @Test + public void givenAutowireInBeanPostProcessor_whenSpringContextInitialize_thenNotEligibleLogShouldShowAndGroupFieldNotPopulated() { + List notEligibleEvents = memoryAppender.search("Bean 'randomIntGenerator' of type [com.baeldung.autoproxying.RandomIntGenerator] " + + "is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)"); + + assertEquals(1, notEligibleEvents.size()); + assertEquals(0, dataCache.getGroup()); + } +}