All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.bingoohuang.springrestclient.spring.SpringRestClientScannerConfigurer Maven / Gradle / Ivy

package com.github.bingoohuang.springrestclient.spring;

import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyResourceConfigurer;
import org.springframework.beans.factory.config.TypedStringValue;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.util.StringUtils;

import java.util.Map;

import static org.springframework.util.Assert.notNull;

public class SpringRestClientScannerConfigurer implements BeanDefinitionRegistryPostProcessor, InitializingBean, ApplicationContextAware, BeanNameAware {

    private String basePackage;

    private ApplicationContext applicationContext;

    private String beanName;

    private boolean processPropertyPlaceHolders;

    private BeanNameGenerator nameGenerator;

    /*
     * This property lets you set the base package for your mapper interface files.
     * 

* You can set more than one package by using a semicolon or comma as a separator. *

* Mappers will be searched for recursively starting in the specified package(s). * * @param basePackage base package name */ public void setBasePackage(String basePackage) { this.basePackage = basePackage; } public void setProcessPropertyPlaceHolders(boolean processPropertyPlaceHolders) { this.processPropertyPlaceHolders = processPropertyPlaceHolders; } /** * {@inheritDoc} */ public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } /** * {@inheritDoc} */ public void setBeanName(String name) { this.beanName = name; } /** * Gets beanNameGenerator to be used while running the scanner. * * @return the beanNameGenerator BeanNameGenerator that has been configured */ public BeanNameGenerator getNameGenerator() { return nameGenerator; } /** * Sets beanNameGenerator to be used while running the scanner. * * @param nameGenerator the beanNameGenerator to set */ public void setNameGenerator(BeanNameGenerator nameGenerator) { this.nameGenerator = nameGenerator; } /** * {@inheritDoc} */ public void afterPropertiesSet() throws Exception { notNull(this.basePackage, "Property 'basePackage' is required"); } /** * {@inheritDoc} */ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { // left intentionally blank } /** * {@inheritDoc} */ public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { if (this.processPropertyPlaceHolders) { processPropertyPlaceHolders(); } ClassPathSpringRestClientScanner scanner = new ClassPathSpringRestClientScanner(registry); scanner.setResourceLoader(this.applicationContext); scanner.setBeanNameGenerator(this.nameGenerator); scanner.registerFilters(); scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS)); } /* * BeanDefinitionRegistries are called early in application startup, before * BeanFactoryPostProcessors. This means that PropertyResourceConfigurers will not have been * loaded and any property substitution of this class' properties will fail. To avoid this, find * any PropertyResourceConfigurers defined in the context and run them on this class' bean * definition. Then update the values. */ private void processPropertyPlaceHolders() { Map prcs = applicationContext.getBeansOfType(PropertyResourceConfigurer.class); if (!prcs.isEmpty() && applicationContext instanceof GenericApplicationContext) { BeanDefinition mapperScannerBean = ((GenericApplicationContext) applicationContext) .getBeanFactory().getBeanDefinition(beanName); // PropertyResourceConfigurer does not expose any methods to explicitly perform // property placeholder substitution. Instead, create a BeanFactory that just // contains this mapper scanner and post process the factory. DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); factory.registerBeanDefinition(beanName, mapperScannerBean); for (PropertyResourceConfigurer prc : prcs.values()) { prc.postProcessBeanFactory(factory); } PropertyValues values = mapperScannerBean.getPropertyValues(); this.basePackage = updatePropertyValue("basePackage", values); } } private String updatePropertyValue(String propertyName, PropertyValues values) { PropertyValue property = values.getPropertyValue(propertyName); if (property == null) { return null; } Object value = property.getValue(); if (value == null) { return null; } else if (value instanceof String) { return value.toString(); } else if (value instanceof TypedStringValue) { return ((TypedStringValue) value).getValue(); } else { return null; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy