已集成为工具,可直接复制使用
且工具提供动态注册移除bean到spring的上下文中的功能,不过此功能因为GC的关系有一些限制,可详细看下注释或者上手使用一番即可知晓。
import java.lang.annotation.Annotation;
import java.util.Map;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.stereotype.Component;
import io.bosun.support.SysApplicationContext.BeanApplicationContext;
import io.bosun.support.SysApplicationContext.BeanDefinitionRegistrar;
import io.bosun.support.util.StringUtil;
/**
* @author zhuangly
*/
@SuppressWarnings("unchecked")
@Component
@Import({BeanApplicationContext.class, BeanDefinitionRegistrar.class})
public final class SysApplicationContext {
static final class BeanApplicationContext implements ApplicationContextAware {
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
// 还有另外一种直接注入的方式获得applicationContext
SysApplicationContext.applicationContext = applicationContext;
}
}
static final class BeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
SysApplicationContext.registry = registry;
}
}
private static ApplicationContext applicationContext;
private static BeanDefinitionRegistry registry;
public static String[] getBeanNamesByType(Class<?> clazz) {
if (clazz == null) {
return null;
}
return applicationContext.getBeanNamesForType(clazz);
}
public static String[] getBeanNamesByAnno(Class<? extends Annotation> clazz) {
if (clazz == null) {
return null;
}
return applicationContext.getBeanNamesForAnnotation(clazz);
}
public static <T> T getBeanByName(String beanName) {
if (StringUtil.isEmpty(beanName) || !applicationContext.containsBean(beanName)) {
return null;
}
return (T) applicationContext.getBean(beanName);
}
public static <T> T getBeanByType(Class<T> clazz, String beanName) {
if (clazz == null) {
return null;
}
if (StringUtil.isEmpty(beanName)) {
return applicationContext.getBean(clazz);
}
if (!applicationContext.containsBean(beanName)) {
return null;
}
return applicationContext.getBean(beanName, clazz);
}
public static <T> T getBeanByAnno(Class<? extends Annotation> clazz, String beanName) {
if (clazz == null || StringUtil.isEmpty(beanName) || !applicationContext.containsBean(beanName)) {
return null;
}
return (T) applicationContext.findAnnotationOnBean(beanName, clazz);
}
public static <T> Map<String, T> getBeansByType(Class<T> clazz) {
if (clazz == null) {
return null;
}
return applicationContext.getBeansOfType(clazz);
}
public static Map<String, Object> getBeansByAnno(Class<? extends Annotation> clazz) {
if (clazz == null) {
return null;
}
return applicationContext.getBeansWithAnnotation(clazz);
}
public static void registBean(Class<?> clazz, String beanName) {
if (clazz == null || StringUtil.isEmpty(beanName)) {
throw new RuntimeException("registBean params is null");
}
if (applicationContext.containsBean(beanName)) {
throw new RuntimeException("beanName is exist");
}
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(clazz).getBeanDefinition();
SysApplicationContext.registry.registerBeanDefinition(beanName, beanDefinition);
}
/** 这边有一个注意的地方 如果已有对象A引用到这个bean 那么A在不重新从上下文中重新获取的情况下被删除的bean是没有变化的,只有重新从上下文中重新加载一下A,A里面的这个bean才会换成新的 */
public static void removeBean(String beanName) {
if (StringUtil.isEmpty(beanName)) {
return;
}
if (!applicationContext.containsBean(beanName)) {
return;
}
if (!SysApplicationContext.registry.isBeanNameInUse(beanName)) {
return;
}
SysApplicationContext.registry.removeBeanDefinition(beanName);
}
public static boolean containsBean(String name) {
return applicationContext.containsBean(name);
}
public static boolean isSingleton(String name) {
return applicationContext.isSingleton(name);
}
public static Class<? extends Object> getType(String name) {
return applicationContext.getType(name);
}
}