@Configuration public class MainConfiguration implements BeanDefinitionRegistryPostProcessor, Ordered { @Beanprivate SayenBeanDefinitionRegistryPostProcessor sayenBeanDefinitionRegistryPostProcessor = new SayenBeanDefinitionRegistryPostProcessor(); public static SayenBeanFactoryPostProcessorint sayenBeanFactoryPostProcessorgetOrder() { return newsayenBeanDefinitionRegistryPostProcessor.getOrder(); SayenBeanFactoryPostProcessor } public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { sayenBeanDefinitionRegistryPostProcessor.postProcessBeanFactory(beanFactory); } public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanFactory) throws BeansException { sayenBeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry(beanFactory); } @Bean public AutowiredBean autowiredBean() { return new AutowiredBean(); } @Bean @Transform(type = MegaSuperKarim.class) public Karim Karim() { return new Karim(); } @Bean @Transform(type = SuperGuillaume.class) public Guillaume Guillaume() { return new Guillaume(); } @Bean public Yoann Yoann() { return new Yoann(); } @Bean public Nicolas Nicolas() { return new Nicolas(); } @Bean public KarimBeanHolderBeanHolder karimBeanHolderbeanHolder() { return new KarimBeanHolderBeanHolder(); } } public class SayenBeanFactoryPostProcessorTransformFactoryBean implements BeanFactoryPostProcessor, OrderedFactoryBean<Object> { private static Logger logger = LoggerFactory.getLogger(SayenBeanFactoryPostProcessor.class); @Override@Autowired public intprivate getOrder()AutowiredBean {pouet; private Class<?> objectType; return HIGHEST_PRECEDENCE; boolean singleton = }true; @Override public voidObject postProcessBeanFactorygetObject(ConfigurableListableBeanFactory bf) throws BeansExceptionException { DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) bf; for (String originalBeanName :return beanFactoryobjectType.getBeanDefinitionNamesgetConstructor()) { logger.debugnewInstance("beanName:" + originalBeanName); BeanDefinition originalBeanDefinition = beanFactory.getBeanDefinition(originalBeanName);} @Override public ifClass<?> (originalBeanDefinition.isAbstractgetObjectType()) { return continue;objectType; } @Override Transform sayenAnnotationpublic =boolean getMethodAnnotationisSingleton(beanFactory, originalBeanDefinition); { return singleton; Class<?> originalBeanClass = beanFactory.getType(originalBeanName);} public ifvoid setObjectType(sayenAnnotation ==Class<?> nullobjectType) { sayenAnnotationthis.objectType = AnnotationUtils.findAnnotation(originalBeanClass, Transform.class);objectType; } public ifAutowiredBean getPouet(sayenAnnotation == null) { return pouet; } public void continue; setSingleton(boolean singleton) { this.singleton = singleton; } } public class SayenBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor, Ordered { Class<?private extendsstatic Sayan>Logger sayenClasslogger = sayenAnnotationLoggerFactory.typegetLogger(MainConfiguration.class); AnnotatedGenericBeanDefinition sayenFactoryBeanDefinition = new AnnotatedGenericBeanDefinition(@Override public int getOrder() { return 0; TransformFactoryBean.class);} @Override public void setPropertyValuespostProcessBeanFactory(sayenClass,ConfigurableListableBeanFactory sayenFactoryBeanDefinitionbeanFactory); throws BeansException { sayenFactoryBeanDefinition.setPrimary(originalBeanDefinitionlogger.isPrimarydebug()"rien"); } sayenFactoryBeanDefinition.setScope(originalBeanDefinition.getScope());@Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanFactory) throws BeansException sayenFactoryBeanDefinition.setRole(originalBeanDefinition.getRole());{ //DefaultListableBeanFactory beanFactory = sayenFactoryBeanDefinition.setLazyInit(originalBeanDefinition.isLazyInit()DefaultListableBeanFactory); String factoryBeanName = originalBeanName;beanFactory; for logger.debug("remove beanName=" +String originalBeanName + ", " +: originalBeanDefinitionbeanFactory.toStringgetBeanDefinitionNames()); { BeanDefinition originalBeanDefinition = beanFactory.removeBeanDefinitiongetBeanDefinition(originalBeanName); logger.debug("register"original beanName=" + factoryBeanNameoriginalBeanName + ", " + sayenFactoryBeanDefinitionoriginalBeanDefinition.toString()); beanFactoryif (originalBeanDefinition.registerBeanDefinitionisAbstract(factoryBeanName, sayenFactoryBeanDefinition); ) { } } privatecontinue; Transform getMethodAnnotation(DefaultListableBeanFactory beanFactory, } BeanDefinition originalBeanDefinition) { StringTransform originalBeanFactoryBeanNamesayenAnnotation = originalBeanDefinition.getFactoryBeanNamegetMethodAnnotation(beanFactory, originalBeanDefinition); String originalBeanFactoryMethodName = originalBeanDefinition.getFactoryMethodName(); if (originalBeanFactoryBeanName == null ||/*if originalBeanFactoryMethodName(sayenAnnotation == null) { return null; } Class<?> originalBeanFactoryBeanClassoriginalBeanClass = ClassUtilsbeanFactory.getUserClassgetType(beanFactoryoriginalBeanName); sayenAnnotation = AnnotationUtils.getTypefindAnnotation(originalBeanFactoryBeanName)originalBeanClass, Transform.class); try { Method*/if method(sayenAnnotation === originalBeanFactoryBeanClass.getMethod(originalBeanFactoryMethodNamenull); { return AnnotationUtils.getAnnotation(method, Transform.class); continue; } catch (SecurityException e) { }/* throw new RuntimeException(e); } catch*/ (NoSuchMethodException e) { Class<? extends Sayan> throwsayenClass new= RuntimeExceptionsayenAnnotation.type(e); } } RootBeanDefinition sayenFactoryBeanDefinition private= voidnew setPropertyValuesRootBeanDefinition(Class<?> clazzTransformFactoryBean.class, AnnotatedGenericBeanDefinition beanDefinition3/*Autowire.BY_TYPE.value()*/, {true); MutablePropertyValues pvs = new MutablePropertyValuessayenFactoryBeanDefinition.getPropertyValues(); pvs.add("objectType", clazzsayenClass); beanDefinition sayenFactoryBeanDefinition.setPropertyValuesgetPropertyValues(pvs).add("singleton", true); } public static class TransformFactoryBean implements FactoryBean<Sayan> { @Autowired String factoryBeanName = originalBeanName; private AutowiredBean pouet; private Class<?logger.debug("remove extendsbeanName=" Sayan>+ objectType; originalBeanName + ", " + originalBeanDefinition.toString()); boolean singleton; @OverridebeanFactory.removeBeanDefinition(originalBeanName); @Bean logger.debug("register beanName=" + publicfactoryBeanName Sayan+ getObject()", throws" Exception+ {sayenFactoryBeanDefinition.toString()); return objectType.getConstructor()beanFactory.newInstanceregisterBeanDefinition(factoryBeanName, sayenFactoryBeanDefinition); } @Override} private publicTransform Class<?getMethodAnnotation(BeanDefinitionRegistry extendsbeanFactory, Sayan>BeanDefinition getObjectType(originalBeanDefinition) { String originalBeanFactoryBeanName return= objectType;originalBeanDefinition.getFactoryBeanName(); } String originalBeanFactoryMethodName = originalBeanDefinition.getFactoryMethodName(); @Override if (originalBeanFactoryBeanName == null || publicoriginalBeanFactoryMethodName boolean== isSingleton(null) { return singleton;null; } public void setObjectType(Class<?> extendsoriginalBeanFactoryBeanClass Sayan>= objectTypeClassUtils.getUserClass(((DefaultListableBeanFactory)beanFactory).getType(originalBeanFactoryBeanName)); try { this.objectTypeMethod method = objectType;originalBeanFactoryBeanClass.getMethod(originalBeanFactoryMethodName); } return AnnotationUtils.getAnnotation(method, Transform.class); public AutowiredBean getPouet() { } catch (SecurityException e) { return pouet; throw new } RuntimeException(e); public} voidcatch setSingleton(booleanNoSuchMethodException singletone) { this.singletonthrow =new singleton;RuntimeException(e); } } } @Configuration public class MainConfiguration { @Bean public static SayenBeanFactoryPostProcessor sayenBeanFactoryPostProcessor() { return new SayenBeanFactoryPostProcessor(); } @Bean public AutowiredBean autowiredBean() { return new AutowiredBean(); } @Bean @Transform(type = MegaSuperKarim.class) public Karim Karim() { return new Karim(); } @Bean @Transform(type = SuperGuillaume.class) public Guillaume Guillaume() { return new Guillaume(); } @Bean public Yoann Yoann() { return new Yoann(); } @Bean public Nicolas Nicolas() { return new Nicolas(); } @Bean public KarimBeanHolder karimBeanHolder() { return new KarimBeanHolder(); } } public class SayenBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered { private static Logger logger = LoggerFactory.getLogger(SayenBeanFactoryPostProcessor.class); @Override public int getOrder() { return HIGHEST_PRECEDENCE; } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory bf) throws BeansException { DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) bf; for (String originalBeanName : beanFactory.getBeanDefinitionNames()) { logger.debug("beanName:" + originalBeanName); BeanDefinition originalBeanDefinition = beanFactory.getBeanDefinition(originalBeanName); if (originalBeanDefinition.isAbstract()) { continue; } Transform sayenAnnotation = getMethodAnnotation(beanFactory, originalBeanDefinition); Class<?> originalBeanClass = beanFactory.getType(originalBeanName); if (sayenAnnotation == null) { sayenAnnotation = AnnotationUtils.findAnnotation(originalBeanClass, Transform.class); if (sayenAnnotation == null) { continue; } } Class<? extends Sayan> sayenClass = sayenAnnotation.type(); AnnotatedGenericBeanDefinition sayenFactoryBeanDefinition = new AnnotatedGenericBeanDefinition( TransformFactoryBean.class); setPropertyValues(sayenClass, sayenFactoryBeanDefinition); sayenFactoryBeanDefinition.setPrimary(originalBeanDefinition.isPrimary()); sayenFactoryBeanDefinition.setScope(originalBeanDefinition.getScope()); sayenFactoryBeanDefinition.setRole(originalBeanDefinition.getRole()); sayenFactoryBeanDefinition.setLazyInit(originalBeanDefinition.isLazyInit()); String factoryBeanName = originalBeanName; logger.debug("remove beanName=" + originalBeanName + ", " + originalBeanDefinition.toString()); beanFactory.removeBeanDefinition(originalBeanName); logger.debug("register beanName=" + factoryBeanName + ", " + sayenFactoryBeanDefinition.toString()); beanFactory.registerBeanDefinition(factoryBeanName, sayenFactoryBeanDefinition); } } private Transform getMethodAnnotation(DefaultListableBeanFactory beanFactory, BeanDefinition originalBeanDefinition) { String originalBeanFactoryBeanName = originalBeanDefinition.getFactoryBeanName(); String originalBeanFactoryMethodName = originalBeanDefinition.getFactoryMethodName(); if (originalBeanFactoryBeanName == null || originalBeanFactoryMethodName == null) { return null; } Class<?> originalBeanFactoryBeanClass = ClassUtils.getUserClass(beanFactory .getType(originalBeanFactoryBeanName)); try { Method method = originalBeanFactoryBeanClass.getMethod(originalBeanFactoryMethodName); return AnnotationUtils.getAnnotation(method, Transform.class); } catch (SecurityException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } } private void setPropertyValues(Class<?> clazz, AnnotatedGenericBeanDefinition beanDefinition) { MutablePropertyValues pvs = new MutablePropertyValues(); pvs.add("objectType", clazz); beanDefinition.setPropertyValues(pvs); } public static class TransformFactoryBean implements FactoryBean<Sayan> { @Autowired private AutowiredBean pouet; private Class<? extends Sayan> objectType; boolean singleton; @Override @Bean public Sayan getObject() throws Exception { return objectType.getConstructor().newInstance(); } @Override public Class<? extends Sayan> getObjectType() { return objectType; } @Override public boolean isSingleton() { return singleton; } public void setObjectType(Class<? extends Sayan> objectType) { this.objectType = objectType; } public AutowiredBean getPouet() { return pouet; } public void setSingleton(boolean singleton) { this.singleton = singleton; } } } @Configuration public class MainConfiguration implements BeanDefinitionRegistryPostProcessor, Ordered { private SayenBeanDefinitionRegistryPostProcessor sayenBeanDefinitionRegistryPostProcessor = new SayenBeanDefinitionRegistryPostProcessor(); public int getOrder() { return sayenBeanDefinitionRegistryPostProcessor.getOrder(); } public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { sayenBeanDefinitionRegistryPostProcessor.postProcessBeanFactory(beanFactory); } public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanFactory) throws BeansException { sayenBeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry(beanFactory); } @Bean public AutowiredBean autowiredBean() { return new AutowiredBean(); } @Bean @Transform(type = MegaSuperKarim.class) public Karim Karim() { return new Karim(); } @Bean @Transform(type = SuperGuillaume.class) public Guillaume Guillaume() { return new Guillaume(); } @Bean public Yoann Yoann() { return new Yoann(); } @Bean public Nicolas Nicolas() { return new Nicolas(); } @Bean public BeanHolder beanHolder() { return new BeanHolder(); } } public class TransformFactoryBean implements FactoryBean<Object> { @Autowired private AutowiredBean pouet; private Class<?> objectType; boolean singleton = true; @Override public Object getObject() throws Exception { return objectType.getConstructor().newInstance(); } @Override public Class<?> getObjectType() { return objectType; } @Override public boolean isSingleton() { return singleton; } public void setObjectType(Class<?> objectType) { this.objectType = objectType; } public AutowiredBean getPouet() { return pouet; } public void setSingleton(boolean singleton) { this.singleton = singleton; } } public class SayenBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor, Ordered { private static Logger logger = LoggerFactory.getLogger(MainConfiguration.class); @Override public int getOrder() { return 0; } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { logger.debug("rien"); } @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanFactory) throws BeansException { //DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) beanFactory; for (String originalBeanName : beanFactory.getBeanDefinitionNames()) { BeanDefinition originalBeanDefinition = beanFactory.getBeanDefinition(originalBeanName); logger.debug("original beanName=" + originalBeanName + ", " + originalBeanDefinition.toString()); if (originalBeanDefinition.isAbstract()) { continue; } Transform sayenAnnotation = getMethodAnnotation(beanFactory, originalBeanDefinition); /*if (sayenAnnotation == null) { Class<?> originalBeanClass = beanFactory.getType(originalBeanName); sayenAnnotation = AnnotationUtils.findAnnotation(originalBeanClass, Transform.class); */if (sayenAnnotation == null) { continue; }/* }*/ Class<? extends Sayan> sayenClass = sayenAnnotation.type(); RootBeanDefinition sayenFactoryBeanDefinition = new RootBeanDefinition(TransformFactoryBean.class, 3/*Autowire.BY_TYPE.value()*/, true); sayenFactoryBeanDefinition.getPropertyValues().add("objectType", sayenClass); sayenFactoryBeanDefinition.getPropertyValues().add("singleton", true); String factoryBeanName = originalBeanName; logger.debug("remove beanName=" + originalBeanName + ", " + originalBeanDefinition.toString()); beanFactory.removeBeanDefinition(originalBeanName); logger.debug("register beanName=" + factoryBeanName + ", " + sayenFactoryBeanDefinition.toString()); beanFactory.registerBeanDefinition(factoryBeanName, sayenFactoryBeanDefinition); } } private Transform getMethodAnnotation(BeanDefinitionRegistry beanFactory, BeanDefinition originalBeanDefinition) { String originalBeanFactoryBeanName = originalBeanDefinition.getFactoryBeanName(); String originalBeanFactoryMethodName = originalBeanDefinition.getFactoryMethodName(); if (originalBeanFactoryBeanName == null || originalBeanFactoryMethodName == null) { return null; } Class<?> originalBeanFactoryBeanClass = ClassUtils.getUserClass(((DefaultListableBeanFactory)beanFactory).getType(originalBeanFactoryBeanName)); try { Method method = originalBeanFactoryBeanClass.getMethod(originalBeanFactoryMethodName); return AnnotationUtils.getAnnotation(method, Transform.class); } catch (SecurityException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } } @Configuration public class MainConfiguration { @Bean public static SayenBeanFactoryPostProcessor sayenBeanFactoryPostProcessor() { return new SayenBeanFactoryPostProcessor(); } @Bean public AutowiredBean autowiredBean() { return new AutowiredBean(); } @Bean @Transform(type = MegaSuperKarim.class) public Karim Karim() { return new Karim(); } @Bean @Transform(type = SuperGuillaume.class) public Guillaume Guillaume() { return new Guillaume(); } @Bean public Yoann Yoann() { return new Yoann(); } @Bean public Nicolas Nicolas() { return new Nicolas(); } @Bean public KarimBeanHolder karimBeanHolder() { return new KarimBeanHolder(); } } public class SayenBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered { private static Logger logger = LoggerFactory.getLogger(SayenBeanFactoryPostProcessor.class); @Override public int getOrder() { return HIGHEST_PRECEDENCE; } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory bf) throws BeansException { DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) bf; for (String originalBeanName : beanFactory.getBeanDefinitionNames()) { logger.debug("beanName:" + originalBeanName); BeanDefinition originalBeanDefinition = beanFactory.getBeanDefinition(originalBeanName); if (originalBeanDefinition.isAbstract()) { continue; } Transform sayenAnnotation = getMethodAnnotation(beanFactory, originalBeanDefinition); Class<?> originalBeanClass = beanFactory.getType(originalBeanName); if (sayenAnnotation == null) { sayenAnnotation = AnnotationUtils.findAnnotation(originalBeanClass, Transform.class); if (sayenAnnotation == null) { continue; } } Class<? extends Sayan> sayenClass = sayenAnnotation.type(); AnnotatedGenericBeanDefinition sayenFactoryBeanDefinition = new AnnotatedGenericBeanDefinition( TransformFactoryBean.class); setPropertyValues(sayenClass, sayenFactoryBeanDefinition); sayenFactoryBeanDefinition.setPrimary(originalBeanDefinition.isPrimary()); sayenFactoryBeanDefinition.setScope(originalBeanDefinition.getScope()); sayenFactoryBeanDefinition.setRole(originalBeanDefinition.getRole()); sayenFactoryBeanDefinition.setLazyInit(originalBeanDefinition.isLazyInit()); String factoryBeanName = originalBeanName; logger.debug("remove beanName=" + originalBeanName + ", " + originalBeanDefinition.toString()); beanFactory.removeBeanDefinition(originalBeanName); logger.debug("register beanName=" + factoryBeanName + ", " + sayenFactoryBeanDefinition.toString()); beanFactory.registerBeanDefinition(factoryBeanName, sayenFactoryBeanDefinition); } } private Transform getMethodAnnotation(DefaultListableBeanFactory beanFactory, BeanDefinition originalBeanDefinition) { String originalBeanFactoryBeanName = originalBeanDefinition.getFactoryBeanName(); String originalBeanFactoryMethodName = originalBeanDefinition.getFactoryMethodName(); if (originalBeanFactoryBeanName == null || originalBeanFactoryMethodName == null) { return null; } Class<?> originalBeanFactoryBeanClass = ClassUtils.getUserClass(beanFactory .getType(originalBeanFactoryBeanName)); try { Method method = originalBeanFactoryBeanClass.getMethod(originalBeanFactoryMethodName); return AnnotationUtils.getAnnotation(method, Transform.class); } catch (SecurityException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } } private void setPropertyValues(Class<?> clazz, AnnotatedGenericBeanDefinition beanDefinition) { MutablePropertyValues pvs = new MutablePropertyValues(); pvs.add("objectType", clazz); beanDefinition.setPropertyValues(pvs); } public static class TransformFactoryBean implements FactoryBean<Sayan> { @Autowired private AutowiredBean pouet; private Class<? extends Sayan> objectType; boolean singleton; @Override @Bean public Sayan getObject() throws Exception { return objectType.getConstructor().newInstance(); } @Override public Class<? extends Sayan> getObjectType() { return objectType; } @Override public boolean isSingleton() { return singleton; } public void setObjectType(Class<? extends Sayan> objectType) { this.objectType = objectType; } public AutowiredBean getPouet() { return pouet; } public void setSingleton(boolean singleton) { this.singleton = singleton; } } } @Configuration public class MainConfiguration { @Bean public static SayenBeanFactoryPostProcessor sayenBeanFactoryPostProcessor() { return new SayenBeanFactoryPostProcessor(); } @Bean public AutowiredBean autowiredBean() { return new AutowiredBean(); } @Bean @Transform(type = MegaSuperKarim.class) public Karim Karim() { return new Karim(); } @Bean @Transform(type = SuperGuillaume.class) public Guillaume Guillaume() { return new Guillaume(); } @Bean public Yoann Yoann() { return new Yoann(); } @Bean public Nicolas Nicolas() { return new Nicolas(); } @Bean public KarimBeanHolder karimBeanHolder() { return new KarimBeanHolder(); } } public class SayenBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered { private static Logger logger = LoggerFactory.getLogger(SayenBeanFactoryPostProcessor.class); @Override public int getOrder() { return HIGHEST_PRECEDENCE; } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory bf) throws BeansException { DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) bf; for (String originalBeanName : beanFactory.getBeanDefinitionNames()) { logger.debug("beanName:" + originalBeanName); BeanDefinition originalBeanDefinition = beanFactory.getBeanDefinition(originalBeanName); if (originalBeanDefinition.isAbstract()) { continue; } Transform sayenAnnotation = getMethodAnnotation(beanFactory, originalBeanDefinition); Class<?> originalBeanClass = beanFactory.getType(originalBeanName); if (sayenAnnotation == null) { sayenAnnotation = AnnotationUtils.findAnnotation(originalBeanClass, Transform.class); if (sayenAnnotation == null) { continue; } } Class<? extends Sayan> sayenClass = sayenAnnotation.type(); AnnotatedGenericBeanDefinition sayenFactoryBeanDefinition = new AnnotatedGenericBeanDefinition( TransformFactoryBean.class); setPropertyValues(sayenClass, sayenFactoryBeanDefinition); sayenFactoryBeanDefinition.setPrimary(originalBeanDefinition.isPrimary()); sayenFactoryBeanDefinition.setScope(originalBeanDefinition.getScope()); sayenFactoryBeanDefinition.setRole(originalBeanDefinition.getRole()); sayenFactoryBeanDefinition.setLazyInit(originalBeanDefinition.isLazyInit()); String factoryBeanName = originalBeanName; logger.debug("remove beanName=" + originalBeanName + ", " + originalBeanDefinition.toString()); beanFactory.removeBeanDefinition(originalBeanName); logger.debug("register beanName=" + factoryBeanName + ", " + sayenFactoryBeanDefinition.toString()); beanFactory.registerBeanDefinition(factoryBeanName, sayenFactoryBeanDefinition); } } private void setPropertyValues(Class<?> clazz, AnnotatedGenericBeanDefinition beanDefinition) { MutablePropertyValues pvs = new MutablePropertyValues(); pvs.add("objectType", clazz); beanDefinition.setPropertyValues(pvs); } public static class TransformFactoryBean implements FactoryBean<Sayan> { @Autowired private AutowiredBean pouet; private Class<? extends Sayan> objectType; boolean singleton; @Override @Bean public Sayan getObject() throws Exception { return objectType.getConstructor().newInstance(); } @Override public Class<? extends Sayan> getObjectType() { return objectType; } @Override public boolean isSingleton() { return singleton; } public void setObjectType(Class<? extends Sayan> objectType) { this.objectType = objectType; } public AutowiredBean getPouet() { return pouet; } public void setSingleton(boolean singleton) { this.singleton = singleton; } } @Configuration public class MainConfiguration { @Bean public static SayenBeanFactoryPostProcessor sayenBeanFactoryPostProcessor() { return new SayenBeanFactoryPostProcessor(); } @Bean public AutowiredBean autowiredBean() { return new AutowiredBean(); } @Bean @Transform(type = MegaSuperKarim.class) public Karim Karim() { return new Karim(); } @Bean @Transform(type = SuperGuillaume.class) public Guillaume Guillaume() { return new Guillaume(); } @Bean public Yoann Yoann() { return new Yoann(); } @Bean public Nicolas Nicolas() { return new Nicolas(); } @Bean public KarimBeanHolder karimBeanHolder() { return new KarimBeanHolder(); } } public class SayenBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered { private static Logger logger = LoggerFactory.getLogger(SayenBeanFactoryPostProcessor.class); @Override public int getOrder() { return HIGHEST_PRECEDENCE; } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory bf) throws BeansException { DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) bf; for (String originalBeanName : beanFactory.getBeanDefinitionNames()) { logger.debug("beanName:" + originalBeanName); BeanDefinition originalBeanDefinition = beanFactory.getBeanDefinition(originalBeanName); if (originalBeanDefinition.isAbstract()) { continue; } Transform sayenAnnotation = getMethodAnnotation(beanFactory, originalBeanDefinition); Class<?> originalBeanClass = beanFactory.getType(originalBeanName); if (sayenAnnotation == null) { sayenAnnotation = AnnotationUtils.findAnnotation(originalBeanClass, Transform.class); if (sayenAnnotation == null) { continue; } } Class<? extends Sayan> sayenClass = sayenAnnotation.type(); AnnotatedGenericBeanDefinition sayenFactoryBeanDefinition = new AnnotatedGenericBeanDefinition( TransformFactoryBean.class); setPropertyValues(sayenClass, sayenFactoryBeanDefinition); sayenFactoryBeanDefinition.setPrimary(originalBeanDefinition.isPrimary()); sayenFactoryBeanDefinition.setScope(originalBeanDefinition.getScope()); sayenFactoryBeanDefinition.setRole(originalBeanDefinition.getRole()); sayenFactoryBeanDefinition.setLazyInit(originalBeanDefinition.isLazyInit()); String factoryBeanName = originalBeanName; logger.debug("remove beanName=" + originalBeanName + ", " + originalBeanDefinition.toString()); beanFactory.removeBeanDefinition(originalBeanName); logger.debug("register beanName=" + factoryBeanName + ", " + sayenFactoryBeanDefinition.toString()); beanFactory.registerBeanDefinition(factoryBeanName, sayenFactoryBeanDefinition); } } private Transform getMethodAnnotation(DefaultListableBeanFactory beanFactory, BeanDefinition originalBeanDefinition) { String originalBeanFactoryBeanName = originalBeanDefinition.getFactoryBeanName(); String originalBeanFactoryMethodName = originalBeanDefinition.getFactoryMethodName(); if (originalBeanFactoryBeanName == null || originalBeanFactoryMethodName == null) { return null; } Class<?> originalBeanFactoryBeanClass = ClassUtils.getUserClass(beanFactory .getType(originalBeanFactoryBeanName)); try { Method method = originalBeanFactoryBeanClass.getMethod(originalBeanFactoryMethodName); return AnnotationUtils.getAnnotation(method, Transform.class); } catch (SecurityException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } } private void setPropertyValues(Class<?> clazz, AnnotatedGenericBeanDefinition beanDefinition) { MutablePropertyValues pvs = new MutablePropertyValues(); pvs.add("objectType", clazz); beanDefinition.setPropertyValues(pvs); } public static class TransformFactoryBean implements FactoryBean<Sayan> { @Autowired private AutowiredBean pouet; private Class<? extends Sayan> objectType; boolean singleton; @Override @Bean public Sayan getObject() throws Exception { return objectType.getConstructor().newInstance(); } @Override public Class<? extends Sayan> getObjectType() { return objectType; } @Override public boolean isSingleton() { return singleton; } public void setObjectType(Class<? extends Sayan> objectType) { this.objectType = objectType; } public AutowiredBean getPouet() { return pouet; } public void setSingleton(boolean singleton) { this.singleton = singleton; } } } @Configuration public class MainConfiguration { @Bean public static SayenBeanFactoryPostProcessor sayenBeanFactoryPostProcessor() { return new SayenBeanFactoryPostProcessor(); } @Bean public AutowiredBean autowiredBean() { return new AutowiredBean(); } @Bean @Transform(type = MegaSuperKarim.class) public Karim Karim() { return new Karim(); } @Bean @Transform(type = SuperGuillaume.class) public Guillaume Guillaume() { return new Guillaume(); } @Bean public Yoann Yoann() { return new Yoann(); } @Bean public Nicolas Nicolas() { return new Nicolas(); } @Bean public KarimBeanHolder karimBeanHolder() { return new KarimBeanHolder(); } } public class SayenBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered { private static Logger logger = LoggerFactory.getLogger(SayenBeanFactoryPostProcessor.class); @Override public int getOrder() { return HIGHEST_PRECEDENCE; } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory bf) throws BeansException { DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) bf; for (String originalBeanName : beanFactory.getBeanDefinitionNames()) { logger.debug("beanName:" + originalBeanName); BeanDefinition originalBeanDefinition = beanFactory.getBeanDefinition(originalBeanName); if (originalBeanDefinition.isAbstract()) { continue; } Transform sayenAnnotation = getMethodAnnotation(beanFactory, originalBeanDefinition); Class<?> originalBeanClass = beanFactory.getType(originalBeanName); if (sayenAnnotation == null) { sayenAnnotation = AnnotationUtils.findAnnotation(originalBeanClass, Transform.class); if (sayenAnnotation == null) { continue; } } Class<? extends Sayan> sayenClass = sayenAnnotation.type(); AnnotatedGenericBeanDefinition sayenFactoryBeanDefinition = new AnnotatedGenericBeanDefinition( TransformFactoryBean.class); setPropertyValues(sayenClass, sayenFactoryBeanDefinition); String factoryBeanMethodName = factoryMethodName(sayenFactoryBeanDefinition); String factoryBeanName = originalBeanClass.getSimpleName() + sayenClass.getSimpleName() + "FactoryBean"; loggersayenFactoryBeanDefinition.debugsetPrimary("registeroriginalBeanDefinition.isPrimary()); beanName=" + factoryBeanName + ", " + sayenFactoryBeanDefinition.toStringsetScope(originalBeanDefinition.getScope()); beanFactorysayenFactoryBeanDefinition.registerBeanDefinitionsetRole(factoryBeanName,originalBeanDefinition.getRole()); sayenFactoryBeanDefinition.setLazyInit(originalBeanDefinition.isLazyInit()); String factoryBeanName = originalBeanName; String newBeanName = originalBeanName; BeanDefinition newBeanDefinition = new AnnotatedGenericBeanDefinition(sayenClass); //BeanDefinition newBeanDefinition = originalBeanDefinition; //newBeanDefinition.setPrimary(originalBeanDefinition.isPrimary()); //newBeanDefinition.setScope(originalBeanDefinition.getScope()); //newBeanDefinition.setAutowireCandidate(originalBeanDefinition.isAutowireCandidate()); //newBeanDefinition.setRole(originalBeanDefinition.getRole()); //newBeanDefinition.setLazyInit(originalBeanDefinition.isLazyInit()); //newBeanDefinition.setOriginatingBeanDefinition(originalBeanDefinition); newBeanDefinition.setFactoryBeanName(factoryBeanName); newBeanDefinition.setFactoryMethodName(factoryBeanMethodName); //newBeanDefinition.setBeanClassName(sayenAnnotation.type().getName()); logger.debug("remove beanName=" + originalBeanName + ", " + originalBeanDefinition.toString()); beanFactory.removeBeanDefinition(originalBeanName); logger.debug("register beanName=" + newBeanName + ", " + newBeanDefinition.toString()); beanFactory.registerBeanDefinition(newBeanName, newBeanDefinition); //Object bean = beanFactory.getBean(factoryBeanName); //bean.toString(); } } private Transform getMethodAnnotation(DefaultListableBeanFactory beanFactory, BeanDefinition originalBeanDefinition) { String originalBeanFactoryBeanName = originalBeanDefinitionlogger.getFactoryBeanNamedebug(); "register beanName=" + factoryBeanName + ", String" originalBeanFactoryMethodName =+ originalBeanDefinitionsayenFactoryBeanDefinition.getFactoryMethodNametoString()); if (originalBeanFactoryBeanName == null || originalBeanFactoryMethodName ==beanFactory.registerBeanDefinition(factoryBeanName, nullsayenFactoryBeanDefinition) { return null; }; Class<?> originalBeanFactoryBeanClass = ClassUtils.getUserClass(beanFactory.getType(originalBeanFactoryBeanName)); try { Method method = originalBeanFactoryBeanClass.getMethod(originalBeanFactoryMethodName); return AnnotationUtils.getAnnotation(method, Transform.class); } catch (SecurityException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } } private void setPropertyValues(Class<?> clazz, AnnotatedGenericBeanDefinition beanDefinition) { MutablePropertyValues pvs = new MutablePropertyValues(); pvs.add("objectType", clazz); beanDefinition.setPropertyValues(pvs); } private String factoryMethodName(AnnotatedGenericBeanDefinition beanDefinition) { AnnotationMetadata metadata = beanDefinition.getMetadata(); Set<MethodMetadata> annotatedMethodspublic =static metadata.getAnnotatedMethods(Bean.class.getName()); Assert.isTrue(1 == annotatedMethods.size(), "just one factory method must have @Bean annotation"); MethodMetadata factoryMethod = annotatedMethods.iterator().next(); return factoryMethod.getMethodName(); TransformFactoryBean implements FactoryBean<Sayan> }{ public@Autowired static class TransformFactoryBean implementsprivate FactoryBean<Sayan>AutowiredBean {pouet; @Autowired private Class<? privateextends AutowiredBeanSayan> pouet;objectType; private Class<Sayan>boolean objectType;singleton; @Override @Bean public Sayan getObject() throws Exception { return objectType.getConstructor().newInstance(); } @Override public Class<Sayan> getObjectType() { return objectType; } @Override public boolean isSingleton() { return true; } public void setObjectType(Class<Sayan> objectType) { this.objectType = objectType; } @Override public AutowiredBeanClass<? getPouetextends Sayan> getObjectType() { return objectType; return pouet;} @Override public boolean isSingleton() { return singleton; } public void setObjectType(Class<? extends Sayan> objectType) { this.objectType = objectType; } public AutowiredBean getPouet() { return pouet; } public void setSingleton(boolean singleton) { this.singleton = singleton; } } @Configuration public class MainConfiguration { @Bean public static SayenBeanFactoryPostProcessor sayenBeanFactoryPostProcessor() { return new SayenBeanFactoryPostProcessor(); } @Bean public AutowiredBean autowiredBean() { return new AutowiredBean(); } @Bean @Transform(type = MegaSuperKarim.class) public Karim Karim() { return new Karim(); } @Bean @Transform(type = SuperGuillaume.class) public Guillaume Guillaume() { return new Guillaume(); } @Bean public Yoann Yoann() { return new Yoann(); } @Bean public Nicolas Nicolas() { return new Nicolas(); } @Bean public KarimBeanHolder karimBeanHolder() { return new KarimBeanHolder(); } } public class SayenBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered { private static Logger logger = LoggerFactory.getLogger(SayenBeanFactoryPostProcessor.class); @Override public int getOrder() { return HIGHEST_PRECEDENCE; } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory bf) throws BeansException { DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) bf; for (String originalBeanName : beanFactory.getBeanDefinitionNames()) { logger.debug("beanName:" + originalBeanName); BeanDefinition originalBeanDefinition = beanFactory.getBeanDefinition(originalBeanName); if (originalBeanDefinition.isAbstract()) { continue; } Transform sayenAnnotation = getMethodAnnotation(beanFactory, originalBeanDefinition); Class<?> originalBeanClass = beanFactory.getType(originalBeanName); if (sayenAnnotation == null) { sayenAnnotation = AnnotationUtils.findAnnotation(originalBeanClass, Transform.class); if (sayenAnnotation == null) { continue; } } Class<? extends Sayan> sayenClass = sayenAnnotation.type(); AnnotatedGenericBeanDefinition sayenFactoryBeanDefinition = new AnnotatedGenericBeanDefinition(TransformFactoryBean.class); setPropertyValues(sayenClass, sayenFactoryBeanDefinition); String factoryBeanMethodName = factoryMethodName(sayenFactoryBeanDefinition); String factoryBeanName = originalBeanClass.getSimpleName() + sayenClass.getSimpleName() + "FactoryBean"; logger.debug("register beanName=" + factoryBeanName + ", " + sayenFactoryBeanDefinition.toString()); beanFactory.registerBeanDefinition(factoryBeanName, sayenFactoryBeanDefinition); String newBeanName = originalBeanName; BeanDefinition newBeanDefinition = new AnnotatedGenericBeanDefinition(sayenClass); //BeanDefinition newBeanDefinition = originalBeanDefinition; //newBeanDefinition.setPrimary(originalBeanDefinition.isPrimary()); //newBeanDefinition.setScope(originalBeanDefinition.getScope()); //newBeanDefinition.setAutowireCandidate(originalBeanDefinition.isAutowireCandidate()); //newBeanDefinition.setRole(originalBeanDefinition.getRole()); //newBeanDefinition.setLazyInit(originalBeanDefinition.isLazyInit()); //newBeanDefinition.setOriginatingBeanDefinition(originalBeanDefinition); newBeanDefinition.setFactoryBeanName(factoryBeanName); newBeanDefinition.setFactoryMethodName(factoryBeanMethodName); //newBeanDefinition.setBeanClassName(sayenAnnotation.type().getName()); logger.debug("remove beanName=" + originalBeanName + ", " + originalBeanDefinition.toString()); beanFactory.removeBeanDefinition(originalBeanName); logger.debug("register beanName=" + newBeanName + ", " + newBeanDefinition.toString()); beanFactory.registerBeanDefinition(newBeanName, newBeanDefinition); //Object bean = beanFactory.getBean(factoryBeanName); //bean.toString(); } } private Transform getMethodAnnotation(DefaultListableBeanFactory beanFactory, BeanDefinition originalBeanDefinition) { String originalBeanFactoryBeanName = originalBeanDefinition.getFactoryBeanName(); String originalBeanFactoryMethodName = originalBeanDefinition.getFactoryMethodName(); if (originalBeanFactoryBeanName == null || originalBeanFactoryMethodName == null) { return null; } Class<?> originalBeanFactoryBeanClass = ClassUtils.getUserClass(beanFactory.getType(originalBeanFactoryBeanName)); try { Method method = originalBeanFactoryBeanClass.getMethod(originalBeanFactoryMethodName); return AnnotationUtils.getAnnotation(method, Transform.class); } catch (SecurityException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } } private void setPropertyValues(Class<?> clazz, AnnotatedGenericBeanDefinition beanDefinition) { MutablePropertyValues pvs = new MutablePropertyValues(); pvs.add("objectType", clazz); beanDefinition.setPropertyValues(pvs); } private String factoryMethodName(AnnotatedGenericBeanDefinition beanDefinition) { AnnotationMetadata metadata = beanDefinition.getMetadata(); Set<MethodMetadata> annotatedMethods = metadata.getAnnotatedMethods(Bean.class.getName()); Assert.isTrue(1 == annotatedMethods.size(), "just one factory method must have @Bean annotation"); MethodMetadata factoryMethod = annotatedMethods.iterator().next(); return factoryMethod.getMethodName(); } public static class TransformFactoryBean implements FactoryBean<Sayan> { @Autowired private AutowiredBean pouet; private Class<Sayan> objectType; @Bean public Sayan getObject() throws Exception { return objectType.getConstructor().newInstance(); } @Override public Class<Sayan> getObjectType() { return objectType; } @Override public boolean isSingleton() { return true; } public void setObjectType(Class<Sayan> objectType) { this.objectType = objectType; } public AutowiredBean getPouet() { return pouet; } } @Configuration public class MainConfiguration { @Bean public static SayenBeanFactoryPostProcessor sayenBeanFactoryPostProcessor() { return new SayenBeanFactoryPostProcessor(); } @Bean public AutowiredBean autowiredBean() { return new AutowiredBean(); } @Bean @Transform(type = MegaSuperKarim.class) public Karim Karim() { return new Karim(); } @Bean @Transform(type = SuperGuillaume.class) public Guillaume Guillaume() { return new Guillaume(); } @Bean public Yoann Yoann() { return new Yoann(); } @Bean public Nicolas Nicolas() { return new Nicolas(); } @Bean public KarimBeanHolder karimBeanHolder() { return new KarimBeanHolder(); } } public class SayenBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered { private static Logger logger = LoggerFactory.getLogger(SayenBeanFactoryPostProcessor.class); @Override public int getOrder() { return HIGHEST_PRECEDENCE; } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory bf) throws BeansException { DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) bf; for (String originalBeanName : beanFactory.getBeanDefinitionNames()) { logger.debug("beanName:" + originalBeanName); BeanDefinition originalBeanDefinition = beanFactory.getBeanDefinition(originalBeanName); if (originalBeanDefinition.isAbstract()) { continue; } Transform sayenAnnotation = getMethodAnnotation(beanFactory, originalBeanDefinition); Class<?> originalBeanClass = beanFactory.getType(originalBeanName); if (sayenAnnotation == null) { sayenAnnotation = AnnotationUtils.findAnnotation(originalBeanClass, Transform.class); if (sayenAnnotation == null) { continue; } } Class<? extends Sayan> sayenClass = sayenAnnotation.type(); AnnotatedGenericBeanDefinition sayenFactoryBeanDefinition = new AnnotatedGenericBeanDefinition( TransformFactoryBean.class); setPropertyValues(sayenClass, sayenFactoryBeanDefinition); sayenFactoryBeanDefinition.setPrimary(originalBeanDefinition.isPrimary()); sayenFactoryBeanDefinition.setScope(originalBeanDefinition.getScope()); sayenFactoryBeanDefinition.setRole(originalBeanDefinition.getRole()); sayenFactoryBeanDefinition.setLazyInit(originalBeanDefinition.isLazyInit()); String factoryBeanName = originalBeanName; logger.debug("remove beanName=" + originalBeanName + ", " + originalBeanDefinition.toString()); beanFactory.removeBeanDefinition(originalBeanName); logger.debug("register beanName=" + factoryBeanName + ", " + sayenFactoryBeanDefinition.toString()); beanFactory.registerBeanDefinition(factoryBeanName, sayenFactoryBeanDefinition); } } private void setPropertyValues(Class<?> clazz, AnnotatedGenericBeanDefinition beanDefinition) { MutablePropertyValues pvs = new MutablePropertyValues(); pvs.add("objectType", clazz); beanDefinition.setPropertyValues(pvs); } public static class TransformFactoryBean implements FactoryBean<Sayan> { @Autowired private AutowiredBean pouet; private Class<? extends Sayan> objectType; boolean singleton; @Override @Bean public Sayan getObject() throws Exception { return objectType.getConstructor().newInstance(); } @Override public Class<? extends Sayan> getObjectType() { return objectType; } @Override public boolean isSingleton() { return singleton; } public void setObjectType(Class<? extends Sayan> objectType) { this.objectType = objectType; } public AutowiredBean getPouet() { return pouet; } public void setSingleton(boolean singleton) { this.singleton = singleton; } } lang-java