import com.google.common.base.Preconditions;
import com.***.base.component.util.BeanUtil;
import java.util.Map;
/**
* @Description: 处理器上下文
* @Author: LiG
* @Date: 2019/9/18 14:28
* @Version: 1.0
*/
public class HandlerContext{
private Map<Class, Map<String, Class>> context;
public HandlerContext(Map<Class, Map<String, Class>> context) {
this.context = context;
}
/**
* 获取处理器实例
* @param type
* @param value
* @param <T>
* @return
*/
public <T> T getInstance(Class<T> type, String value) {
Class clazz = context.get(type).get(value);
Preconditions.checkNotNull(clazz, "Failed to get the processor, Invalid type or value!!!");
return (T) BeanUtil.getBean(clazz);
}
}
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @Description: 处理器上下文设置
* @Author: LiG
* @Date: 2019/9/18 15:02
* @Version: 1.0
*/
public class HandlerProcessor implements BeanFactoryPostProcessor {
/**
* Modify the application context's internal bean factory after its standard
* initialization. All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for overriding or adding
* properties even to eager-initializing beans.
*
* @param beanFactory the bean factory used by the application context
* @throws BeansException in case of errors
*/
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
Map<Class, Map<String, Class>> context = new HashMap<>(16);
Arrays.stream(beanFactory.getBeanNamesForAnnotation(HandlerOrder.class)).collect(Collectors.groupingBy(className ->
Arrays.stream(beanFactory.getType(className).getAnnotations()).filter(annotation -> annotation instanceof HandlerOrder).
map(annotation -> ((HandlerOrder) annotation).type()).findFirst().get()
)).forEach((clazz, list) -> context.put(clazz, list.stream().collect(Collectors.toMap(className ->
Arrays.stream(beanFactory.getType(className).getAnnotations()).filter(annotation -> annotation instanceof HandlerOrder).
map(annotation -> ((HandlerOrder) annotation).value()).findFirst().get(),
className -> beanFactory.getType(className), (oldValue, newValue) -> newValue))));
HandlerContext handlerContext = new HandlerContext(context);
beanFactory.registerSingleton(HandlerContext.class.getName(), handlerContext);
}
}
import org.springframework.context.ApplicationContext;
/**
* @Description: BeanUtil,提供各种applicationContext的方法的简单代理
* @Author: LiG
* @Date: 2019/9/19 10:32
* @Version: 1.0
*/
public class BeanUtil {
private static ApplicationContext applicationContext;
public static <T> T getBean(Class<T> requiredType) {
return applicationContext.getBean(requiredType);
}
public static void setApplicationContext(ApplicationContext applicationContext) {
BeanUtil.applicationContext = applicationContext;
}
}
import com.***.base.component.handler.HandlerProcessor;
import com.***.base.component.util.BeanUtil;
import org.springframework.beans.BeansException;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Description: 公共组件beans
* @Author: LiG
* @Date: 2019/9/18 18:18
* @Version: 1.0
*/
@Configuration
public class ComponentConfiguration implements ApplicationContextAware {
@Bean
@ConditionalOnProperty(prefix = "base.component", name = "handler", havingValue = "true")
public HandlerProcessor handlerProcessor() {
return new HandlerProcessor();
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
BeanUtil.setApplicationContext(applicationContext);
}
}