Spring获得ApplicationContext的一种方式

已集成为工具,可直接复制使用

且工具提供动态注册移除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);
	}
}

猜你喜欢

转载自blog.csdn.net/yaseno1/article/details/124688103