From e38d9dc767341596b8798382be79b1ed9224eabe Mon Sep 17 00:00:00 2001 From: Avinash Date: Mon, 10 Jun 2019 04:19:11 +0530 Subject: [PATCH] Auto Configuring beans without Stereotypes --- .gitignore | 2 + .../java/com/firefly/dp/FactoryProducer.java | 34 +++----- .../java/com/firefly/dp/FireFlyRegistrar.java | 87 +++++++++++++++++++ .../firefly/dp/annotations/EnableFireFly.java | 10 ++- .../com/firefly/dp/helper/FactoryHelper.java | 29 ------- .../dp/helper/FactoryMemberHelper.java | 23 ++--- 6 files changed, 113 insertions(+), 72 deletions(-) create mode 100644 src/main/java/com/firefly/dp/FireFlyRegistrar.java delete mode 100644 src/main/java/com/firefly/dp/helper/FactoryHelper.java diff --git a/.gitignore b/.gitignore index 63177e3..bae47e2 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ HELP.md .gradle /build/ !gradle/wrapper/gradle-wrapper.jar +classes/ +META-INF ### STS ### .apt_generated diff --git a/src/main/java/com/firefly/dp/FactoryProducer.java b/src/main/java/com/firefly/dp/FactoryProducer.java index 3e2620a..9a540d5 100644 --- a/src/main/java/com/firefly/dp/FactoryProducer.java +++ b/src/main/java/com/firefly/dp/FactoryProducer.java @@ -1,42 +1,32 @@ package com.firefly.dp; import com.firefly.dp.annotations.FactoryMember; -import com.firefly.dp.helper.FactoryHelper; import com.firefly.dp.helper.FactoryMemberHelper; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.lang.annotation.Annotation; import java.util.List; import java.util.Optional; import java.util.stream.Stream; -@Component public class FactoryProducer { - @Autowired - private FactoryMemberHelper factoryMember; - - @Autowired - private FactoryHelper factoryHelper; + private List factoryMembers; public T getImplemention(Class clazz, String value) { - if (factoryHelper.isFireFlyEnabled()) { - List implementedClazz = factoryMember.accumulateByParent(clazz); - for (Object o : implementedClazz) { - Annotation[] annotations = o.getClass().getAnnotations(); - Optional first = Stream.of(annotations) - .filter(annotation -> annotation.annotationType().equals(FactoryMember.class)) - .findFirst(); - if (first.isPresent()) { - FactoryMember annotation = (FactoryMember) first.get(); - if (annotation.key().equalsIgnoreCase(value)) - return (T) o; - } + List implementedClazz = new FactoryMemberHelper(this.factoryMembers, clazz).accumulateByParent(); + for (Object o : implementedClazz) { + Annotation[] annotations = o.getClass().getAnnotations(); + Optional first = Stream.of(annotations) + .filter(annotation -> annotation.annotationType().equals(FactoryMember.class)) + .findFirst(); + if (first.isPresent()) { + FactoryMember annotation = (FactoryMember) first.get(); + if (annotation.key().equalsIgnoreCase(value)) + return (T) o; } } - throw new RuntimeException("FireFly not enabled"); + throw new RuntimeException("FireFly not enabled"); } } diff --git a/src/main/java/com/firefly/dp/FireFlyRegistrar.java b/src/main/java/com/firefly/dp/FireFlyRegistrar.java new file mode 100644 index 0000000..1f2c8e6 --- /dev/null +++ b/src/main/java/com/firefly/dp/FireFlyRegistrar.java @@ -0,0 +1,87 @@ +package com.firefly.dp; + +import com.firefly.dp.annotations.FactoryMember; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.BeanDefinitionHolder; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.BeanDefinitionReaderUtils; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.context.EnvironmentAware; +import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; +import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; +import org.springframework.core.env.Environment; +import org.springframework.core.type.AnnotationMetadata; +import org.springframework.core.type.filter.AnnotationTypeFilter; +import org.springframework.util.ClassUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +public class FireFlyRegistrar implements ImportBeanDefinitionRegistrar, EnvironmentAware { + + + private Environment environment; + + @Override + public void setEnvironment(Environment environment) { + this.environment = environment; + } + + @Override + public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) { + try { + List classes = returnRegisteredFireFlies(metadata); + registerBean(registry, classes); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } + + public void registerBean(BeanDefinitionRegistry registry, List clazz) throws BeansException { + + BeanDefinition dynamicBean = BeanDefinitionBuilder + .rootBeanDefinition(FactoryProducer.class) + .addPropertyValue("factoryMembers", clazz) + .getBeanDefinition(); + BeanDefinitionHolder holder = new BeanDefinitionHolder(dynamicBean, FactoryProducer.class.getName(), new String[]{"Factory-Producer"}); + + BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry); + + } + + + public List returnRegisteredFireFlies(AnnotationMetadata metadata) throws ClassNotFoundException { + ClassPathScanningCandidateComponentProvider scanner = getScanner(); + AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter(FactoryMember.class); + scanner.addIncludeFilter(annotationTypeFilter); + String packageName = ClassUtils.getPackageName(metadata.getClassName()); + Set candidateComponents = scanner.findCandidateComponents(packageName); + List clazzList = new ArrayList<>(); + + for (BeanDefinition bean : candidateComponents) { + clazzList.add(Class.forName(bean.getBeanClassName())); + } + + return clazzList; + } + + protected ClassPathScanningCandidateComponentProvider getScanner() { + return new ClassPathScanningCandidateComponentProvider(false, this.environment) { + @Override + protected boolean isCandidateComponent( + AnnotatedBeanDefinition beanDefinition) { + boolean isCandidate = false; + if (beanDefinition.getMetadata().isIndependent()) { + if (!beanDefinition.getMetadata().isAnnotation()) { + isCandidate = true; + } + } + return isCandidate; + } + }; + } + +} diff --git a/src/main/java/com/firefly/dp/annotations/EnableFireFly.java b/src/main/java/com/firefly/dp/annotations/EnableFireFly.java index a6323a4..ef6725f 100644 --- a/src/main/java/com/firefly/dp/annotations/EnableFireFly.java +++ b/src/main/java/com/firefly/dp/annotations/EnableFireFly.java @@ -1,11 +1,13 @@ package com.firefly.dp.annotations; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +import com.firefly.dp.FireFlyRegistrar; +import org.springframework.context.annotation.Import; + +import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) +@Documented +@Import(FireFlyRegistrar.class) public @interface EnableFireFly { } diff --git a/src/main/java/com/firefly/dp/helper/FactoryHelper.java b/src/main/java/com/firefly/dp/helper/FactoryHelper.java deleted file mode 100644 index fd11b3a..0000000 --- a/src/main/java/com/firefly/dp/helper/FactoryHelper.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.firefly.dp.helper; - - -import com.firefly.dp.annotations.EnableFireFly; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; - -import java.util.ArrayList; -import java.util.List; - -@Component -public class FactoryHelper { - - @Autowired - private ApplicationContext context; - - public List getFireFlyClass() { - return new ArrayList<>(context.getBeansWithAnnotation(EnableFireFly.class).values()); - } - - public Boolean isFireFlyEnabled() { - if (!CollectionUtils.isEmpty(getFireFlyClass())) - return true; - return false; - } - -} diff --git a/src/main/java/com/firefly/dp/helper/FactoryMemberHelper.java b/src/main/java/com/firefly/dp/helper/FactoryMemberHelper.java index f969020..f719318 100644 --- a/src/main/java/com/firefly/dp/helper/FactoryMemberHelper.java +++ b/src/main/java/com/firefly/dp/helper/FactoryMemberHelper.java @@ -1,31 +1,20 @@ package com.firefly.dp.helper; -import com.firefly.dp.annotations.FactoryMember; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.stereotype.Component; +import lombok.AllArgsConstructor; -import javax.annotation.PostConstruct; -import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; -@Component +@AllArgsConstructor public class FactoryMemberHelper { - @Autowired - private ApplicationContext context; + private List fireFlyClazz; - private List fireFlyClazz; + private Class parentClass; - @PostConstruct - public void initiator() { - this.fireFlyClazz = new ArrayList<>(context.getBeansWithAnnotation(FactoryMember.class).values()); - } - - public List accumulateByParent(Class parent) { + public List accumulateByParent() { return this.fireFlyClazz.stream() - .filter(clazz -> parent.isAssignableFrom(clazz.getClass())) + .filter(clazz -> parentClass.isAssignableFrom(clazz)) .collect(Collectors.toList()); } }