vertx限流

This commit is contained in:
ztzh_xieyun 2024-04-26 15:30:30 +08:00
parent 99fcb47f55
commit 220ec74d5a
15 changed files with 562 additions and 55 deletions

View File

@ -0,0 +1,18 @@
package com.sf.vertx.api.pojo;
import java.io.Serializable;
import lombok.Data;
@Data
public class ApiCurrentLimitingConfig implements Serializable {
private static final long serialVersionUID = 8042924090032324660L;
private Integer threshold; // 2, // 限流阈值
private Integer timeWindow; //1, //时间窗口单位s
private String defaultResponse;
// ": "{
// \"msg\": \"接口繁忙请重试\",
// \"code\": 501,
// \"data\": \"到达限流阈值\",
// }" // 默认限流响应JSON字符串。
}

View File

@ -0,0 +1,18 @@
package com.sf.vertx.api.pojo;
import java.io.Serializable;
import lombok.Data;
@Data
public class AppCurrentLimitingConfig implements Serializable {
private static final long serialVersionUID = 5851544674347437522L;
private Integer threshold; // 2, // 限流阈值(APP总和)
private Integer timeWindow; //1, //时间窗口单位s
private String defaultResponse;
// ": "{
// \"msg\": \"接口繁忙请重试\",
// \"code\": 501,
// \"data\": \"到达限流阈值\",
// }" // 默认限流响应JSON字符串。
}

View File

@ -1,4 +1,6 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/main/resources=UTF-8
encoding//src/test/java=UTF-8
encoding//src/test/resources=UTF-8
encoding/<project>=UTF-8

View File

@ -0,0 +1,48 @@
package com.sf.vertx.config;
import java.nio.charset.Charset;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.JSONWriter;
/**
* Redis使用FastJson序列化
*
* @author ztzh
*/
public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>
{
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private Class<T> clazz;
public FastJson2JsonRedisSerializer(Class<T> clazz)
{
super();
this.clazz = clazz;
}
@Override
public byte[] serialize(T t) throws SerializationException
{
if (t == null)
{
return new byte[0];
}
return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(DEFAULT_CHARSET);
}
@Override
public T deserialize(byte[] bytes) throws SerializationException
{
if (bytes == null || bytes.length <= 0)
{
return null;
}
String str = new String(bytes, DEFAULT_CHARSET);
return JSON.parseObject(str, clazz, JSONReader.Feature.SupportAutoType);
}
}

View File

@ -0,0 +1,69 @@
package com.sf.vertx.config;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* redis配置
*
* @author ztzh
*/
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport
{
@Bean(name = "redisTemplate")
@SuppressWarnings(value = { "unchecked", "rawtypes" })
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory)
{
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);
// 使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(serializer);
// Hash的key也采用StringRedisSerializer的序列化方式
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(serializer);
template.afterPropertiesSet();
return template;
}
@Bean
public DefaultRedisScript<Long> limitScript()
{
DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
redisScript.setScriptText(limitScriptText());
redisScript.setResultType(Long.class);
return redisScript;
}
/**
* 限流脚本
*/
private String limitScriptText()
{
return "local key = KEYS[1]\n" +
"local count = tonumber(ARGV[1])\n" +
"local time = tonumber(ARGV[2])\n" +
"local current = redis.call('get', key);\n" +
"if current and tonumber(current) > count then\n" +
" return tonumber(current);\n" +
"end\n" +
"current = redis.call('incr', key)\n" +
"if tonumber(current) == 1 then\n" +
" redis.call('expire', key, time)\n" +
"end\n" +
"return tonumber(current);";
}
}

View File

@ -3,22 +3,22 @@ package com.sf.vertx.constans;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class RedisConfig {
public class RedisKeyConfig {
@Value("${server.vertx.environment}")
private String vertxEnvironment;
private String vertxEnvironment;
public static final String BASE_REDIS_KEY = "vertx:config:";
public static String APP_CONFIG_SET_KEY = null;
public static String APP_CURRENT_LIMITING_CONFIG_KEY = null;
public static String APP_CONFIG_PREFIX_KEY = null;
public static String VERTX_CONFIG_STRING_KEY = null;
public void init() {
APP_CONFIG_PREFIX_KEY = BASE_REDIS_KEY + vertxEnvironment;
APP_CONFIG_SET_KEY = APP_CONFIG_PREFIX_KEY+":set";
APP_CONFIG_SET_KEY = APP_CONFIG_PREFIX_KEY + ":set";
APP_CURRENT_LIMITING_CONFIG_KEY = APP_CONFIG_PREFIX_KEY + ":app";
VERTX_CONFIG_STRING_KEY = BASE_REDIS_KEY + vertxEnvironment + ":vertx";
}
}

View File

@ -0,0 +1,27 @@
package com.sf.vertx.handle;
import io.vertx.codegen.annotations.VertxGen;
import io.vertx.core.Handler;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.RoutingContext;
/***
* 限流熔断, redis存储
* @author xy
*
*/
@VertxGen
public interface RateLimitHandler extends Handler<RoutingContext> {
static RateLimitHandler create(String instance) {
switch (instance) {
case "redis":
RedisRateLimiter redisRateLimiter = new RedisRateLimiter();
return new RateLimitHandlerRedisImpl(redisRateLimiter);
default:
// 本地缓存
return null;
}
}
}

View File

@ -0,0 +1,10 @@
package com.sf.vertx.handle;
/***
* 内存存储
* @author xy
*
*/
public class RateLimitHandlerImpl {
}

View File

@ -0,0 +1,51 @@
package com.sf.vertx.handle;
import com.sf.vertx.api.pojo.AppCurrentLimitingConfig;
import com.sf.vertx.init.DynamicBuildServer;
import com.sf.vertx.service.impl.AppConfigServiceImpl;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.handler.HttpException;
import lombok.extern.slf4j.Slf4j;
/***
* redis存储
*
* @author xy
*
*/
@Slf4j
public class RateLimitHandlerRedisImpl implements RateLimitHandler {
private RedisRateLimiter rateLimiter;
public RateLimitHandlerRedisImpl(RedisRateLimiter rateLimiter) {
this.rateLimiter = rateLimiter;
}
@Override
public void handle(RoutingContext rc) {
String sacAppHeaderKey = rc.request().headers().get(DynamicBuildServer.SAC_APP_HEADER_KEY);
// TODO 判断是否开启限流配置
log.info("RateLimitHandlerRedisImpl request:{}", sacAppHeaderKey);
// rc.next();
// return;
// 获取模式
int pattern = 1; // 1:app,2:接口默认,3:服务接口配置限流策略
if (rateLimiter.acquire(rc, pattern)) {
log.info("rateLimiter.acquire true");
rc.next();
return;
} else {
switch (pattern) {
case 1:
AppCurrentLimitingConfig appCurrentLimitingConfig = AppConfigServiceImpl
.getAppCurrentLimitingConfig(sacAppHeaderKey);
rc.fail(new HttpException(429, appCurrentLimitingConfig.getDefaultResponse()));
return;
// JsonObject dataJson = new JsonObject(appCurrentLimitingConfig.getDefaultResponse());
// rc.response().setChunked(true).setStatusCode(429).putHeader("Content-Type", "application/json").end(dataJson.toBuffer());
// return;
}
}
}
}

View File

@ -0,0 +1,53 @@
package com.sf.vertx.handle;
import java.util.concurrent.TimeUnit;
import org.springframework.data.redis.core.RedisTemplate;
import com.sf.vertx.api.pojo.AppCurrentLimitingConfig;
import com.sf.vertx.constans.RedisKeyConfig;
import com.sf.vertx.init.DynamicBuildServer;
import com.sf.vertx.service.impl.AppConfigServiceImpl;
import com.sf.vertx.utils.SpringUtils;
import io.vertx.ext.web.RoutingContext;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class RedisRateLimiter {
public Boolean acquire(RoutingContext rc, int pattern) {
String appCode = rc.request().headers().get(DynamicBuildServer.SAC_APP_HEADER_KEY);
//TODO 先测试app模式,后面通过app缓存获取模式
switch (pattern) {
case 1:
String key = RedisKeyConfig.APP_CURRENT_LIMITING_CONFIG_KEY +":"+ appCode;
return rateLimiter(key, appCode);
default:
break;
}
return false;
}
@SuppressWarnings("unchecked")
private Boolean rateLimiter(String key, String appCode) {
RedisTemplate<String, Integer> redisTemplate = SpringUtils.getBean("redisTemplate", RedisTemplate.class);
AppCurrentLimitingConfig appCurrentLimitingConfig = AppConfigServiceImpl.getAppCurrentLimitingConfig(appCode);
Object count = redisTemplate.opsForValue().get(key);
//redisTemplate.delete(key);
log.info("count:{}", count);
if(count == null) {
// 初始化,设置过期时间
redisTemplate.opsForValue().increment(key);
log.info("redis app threshold: {}", redisTemplate.opsForValue().get(key));
redisTemplate.expire(key, appCurrentLimitingConfig.getTimeWindow(), TimeUnit.SECONDS);
} else if(Integer.valueOf(count.toString()) < appCurrentLimitingConfig.getThreshold()) {
redisTemplate.opsForValue().increment(key);
} else {
return false;
}
return true;
}
}

View File

@ -0,0 +1,10 @@
package com.sf.vertx.handle;
import io.vertx.core.Handler;
import io.vertx.ext.web.RoutingContext;
public interface RestfulFailureHandler extends Handler<RoutingContext> {
static RestfulFailureHandlerImpl create() {
return new RestfulFailureHandlerImpl();
}
}

View File

@ -0,0 +1,23 @@
package com.sf.vertx.handle;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.handler.HttpException;
public class RestfulFailureHandlerImpl implements RestfulFailureHandler {
@Override
public void handle(RoutingContext frc) {
Throwable failure = frc.failure();
if (failure instanceof HttpException) {
HttpException httpException = (HttpException) failure;
// frc.response().setStatusCode(404).end();
JsonObject dataJson = new JsonObject(httpException.getPayload());
frc.response().setChunked(true).setStatusCode(httpException.getStatusCode())
.putHeader("Content-Type", "application/json").end(dataJson.toBuffer());
return;
}
frc.response().setStatusCode(500).setStatusMessage("Server internal error:" + failure.getMessage()).end();
}
}

View File

@ -19,9 +19,11 @@ import com.sf.vertx.api.pojo.SacService;
import com.sf.vertx.api.pojo.VertxConfig;
import com.sf.vertx.arithmetic.roundRobin.SacLoadBalancing;
import com.sf.vertx.arithmetic.roundRobin.WeightedRoundRobin;
import com.sf.vertx.constans.RedisConfig;
import com.sf.vertx.constans.RedisKeyConfig;
import com.sf.vertx.handle.BodyHandler;
import com.sf.vertx.handle.ProxyHandler;
import com.sf.vertx.handle.RateLimitHandler;
import com.sf.vertx.handle.RestfulFailureHandler;
import com.sf.vertx.security.MainSecurity;
import com.sf.vertx.service.AppConfigService;
import com.sf.vertx.service.impl.AppConfigServiceImpl;
@ -33,9 +35,11 @@ import io.vertx.core.http.HttpClient;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerOptions;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.json.JsonObject;
import io.vertx.core.net.SocketAddress;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.client.WebClient;
import io.vertx.ext.web.handler.HttpException;
import io.vertx.httpproxy.HttpProxy;
import io.vertx.httpproxy.ProxyContext;
import io.vertx.httpproxy.ProxyInterceptor;
@ -61,12 +65,12 @@ public class DynamicBuildServer implements ApplicationRunner {
private AppConfigService appConfigService;
@Autowired
private RedisConfig redisConfig;
private RedisKeyConfig redisKeyConfig;
@Override
public void run(ApplicationArguments args) throws Exception {
// 初始化redis key
redisConfig.init();
redisKeyConfig.init();
// 加载vertx应用配置
appStartLoadData();
}
@ -113,16 +117,20 @@ public class DynamicBuildServer implements ApplicationRunner {
// 判断是否需要加解析
if (AppConfigServiceImpl.appDataSecurity(sacAppHeaderKey)) {
//String data = decode(null, sacAppHeaderKey);
// String data = decode(null, sacAppHeaderKey);
}
return context.sendRequest();
}
});
WebClient mainWebClient = WebClient.create(VERTX);
//mainHttpRouter.route().handler(ProxyHandler.create(proxy));
// mainHttpRouter.route().handler(ProxyHandler.create(proxy));
mainHttpRouter.route().handler(BodyHandler.create()).handler(ProxyHandler.create(mainWebClient,proxy));
// TODO 实例化方式 VertxConfig 读取
String instance = "redis";
mainHttpRouter.route().handler(RateLimitHandler.create(instance)).handler(BodyHandler.create())
.handler(ProxyHandler.create(mainWebClient, proxy)).failureHandler(RestfulFailureHandler.create());
// mainHttpRouter.route().handler(BodyHandler.create()).handler(ProxyHandler.create(mainWebClient,proxy));
}
public SocketAddress resolveOriginAddress(ConcurrentHashMap<String, AppConfig> cacheAppConfig,

View File

@ -13,8 +13,9 @@ import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.sf.vertx.api.pojo.AppConfig;
import com.sf.vertx.api.pojo.AppCurrentLimitingConfig;
import com.sf.vertx.api.pojo.VertxConfig;
import com.sf.vertx.constans.RedisConfig;
import com.sf.vertx.constans.RedisKeyConfig;
import com.sf.vertx.service.AppConfigService;
import lombok.extern.slf4j.Slf4j;
@ -23,37 +24,54 @@ import lombok.extern.slf4j.Slf4j;
@Service
public class AppConfigServiceImpl implements AppConfigService {
@Value("${server.vertx.environment}")
private String vertxEnvironment;
private String vertxEnvironment;
@Autowired
private RedisTemplate<String, String> redisTemplate;
private static final ConcurrentHashMap<String, AppConfig> cacheAppConfig = new ConcurrentHashMap<>();
private static final ConcurrentHashMap<String, AppConfig> CACHE_APP_CONFIG = new ConcurrentHashMap<>();
private static final ConcurrentHashMap<String, AppCurrentLimitingConfig> CACHE_APP_CURRENT_LIMITING_CONFIG = new ConcurrentHashMap<>();
public static boolean appDataSecurity(String appCode) {
return cacheAppConfig.get(appCode) != null && cacheAppConfig.get(appCode).getDataSecurity() != null ? true : false;
return CACHE_APP_CONFIG.get(appCode) != null && CACHE_APP_CONFIG.get(appCode).getDataSecurity() != null ? true
: false;
}
public static AppCurrentLimitingConfig getAppCurrentLimitingConfig(String appCode) {
return CACHE_APP_CURRENT_LIMITING_CONFIG.get(appCode);
}
/***
* 从redis加载数据
*/
public ConcurrentHashMap<String, AppConfig> loadAllConfig() {
Set<String> set = redisTemplate.opsForZSet().range(RedisConfig.APP_CONFIG_SET_KEY, 0, -1);
for(String appCode : set) {
String appCodeKey = RedisConfig.APP_CONFIG_PREFIX_KEY + ":" + appCode;
Set<String> set = redisTemplate.opsForZSet().range(RedisKeyConfig.APP_CONFIG_SET_KEY, 0, -1);
for (String appCode : set) {
String appCodeKey = RedisKeyConfig.APP_CONFIG_PREFIX_KEY + ":" + appCode;
String appCodeValue = redisTemplate.opsForValue().get(appCodeKey);
if(StringUtils.isNotBlank(appCodeValue)) {
AppConfig appConfig = JSON.parseObject(appCodeValue, new TypeReference<AppConfig>() {});
cacheAppConfig.put(appCode, appConfig);
if (StringUtils.isNotBlank(appCodeValue)) {
AppConfig appConfig = JSON.parseObject(appCodeValue, new TypeReference<AppConfig>() {
});
CACHE_APP_CONFIG.put(appCode, appConfig);
}
}
log.info("cacheAppConfig:{}", JSON.toJSONString(cacheAppConfig));
return cacheAppConfig;
// TODO 限流
AppCurrentLimitingConfig appCurrentLimitingConfig = new AppCurrentLimitingConfig();
appCurrentLimitingConfig.setThreshold(1);
appCurrentLimitingConfig.setTimeWindow(10);
appCurrentLimitingConfig.setDefaultResponse(
"{\n" + " \"msg\": \"接口繁忙请重试\",\n" + " \"code\": 501,\n" + " \"data\": \"到达限流阈值\"\n" + "}");
CACHE_APP_CURRENT_LIMITING_CONFIG.put("dsafdsfadafhappd", appCurrentLimitingConfig);
CACHE_APP_CURRENT_LIMITING_CONFIG.put("dsafdsfadafhappC", appCurrentLimitingConfig);
log.info("cacheAppConfig:{}", JSON.toJSONString(CACHE_APP_CONFIG));
return CACHE_APP_CONFIG;
}
public AppConfig getAppConfig(String appCode) {
String appCodeKey = RedisConfig.APP_CONFIG_PREFIX_KEY + ":" + appCode;
String appCodeKey = RedisKeyConfig.APP_CONFIG_PREFIX_KEY + ":" + appCode;
String appCodeValue = redisTemplate.opsForValue().get(appCodeKey);
if(StringUtils.isNotBlank(appCodeValue)) {
if (StringUtils.isNotBlank(appCodeValue)) {
AppConfig appConfig = JSONObject.parseObject(appCodeValue, AppConfig.class);
return appConfig;
}
@ -62,41 +80,41 @@ public class AppConfigServiceImpl implements AppConfigService {
/***
* 新增修改
*
* @param appConfig
*/
public void addAppConfig(String appConfigStr) {
AppConfig appConfig = JSON.parseObject(appConfigStr, AppConfig.class);
redisTemplate.opsForZSet().add(RedisConfig.APP_CONFIG_SET_KEY, appConfig.getAppCode(), 0);
String appCodeKey = RedisConfig.APP_CONFIG_PREFIX_KEY + ":" + appConfig.getAppCode();
redisTemplate.opsForZSet().add(RedisKeyConfig.APP_CONFIG_SET_KEY, appConfig.getAppCode(), 0);
String appCodeKey = RedisKeyConfig.APP_CONFIG_PREFIX_KEY + ":" + appConfig.getAppCode();
redisTemplate.opsForValue().set(appCodeKey, appConfigStr);
// 发送redis队列,vertx处理
//String queue = RedisConfig.VETX_ENVIRONMENT_KEY+vertxEnvironment+":list";
// String queue = RedisKeyConfig.VETX_ENVIRONMENT_KEY+vertxEnvironment+":list";
}
/***
* 删除
*
* @param appConfig
*/
public void deleteAppConfig(AppConfig appConfig) {
redisTemplate.opsForZSet().remove(RedisConfig.APP_CONFIG_SET_KEY, appConfig.getAppCode());
String appCodeKey = RedisConfig.APP_CONFIG_PREFIX_KEY + ":" + appConfig.getAppCode();
redisTemplate.opsForZSet().remove(RedisKeyConfig.APP_CONFIG_SET_KEY, appConfig.getAppCode());
String appCodeKey = RedisKeyConfig.APP_CONFIG_PREFIX_KEY + ":" + appConfig.getAppCode();
redisTemplate.delete(appCodeKey);
// 发送redis队列,vertx处理
//String queue = RedisConfig.VETX_ENVIRONMENT_KEY+vertxEnvironment+":list";
// String queue = RedisKeyConfig.VETX_ENVIRONMENT_KEY+vertxEnvironment+":list";
}
/***
* 加载vertx配置
*/
public VertxConfig loadVertxConfig() {
String vertxConfigKey = RedisConfig.VERTX_CONFIG_STRING_KEY;
String vertxConfigKey = RedisKeyConfig.VERTX_CONFIG_STRING_KEY;
String vertxConfigValue = redisTemplate.opsForValue().get(vertxConfigKey);
if(StringUtils.isNotBlank(vertxConfigValue)) {
if (StringUtils.isNotBlank(vertxConfigValue)) {
VertxConfig vertxConfig = JSONObject.parseObject(vertxConfigValue, VertxConfig.class);
return vertxConfig;
}
@ -105,13 +123,14 @@ public class AppConfigServiceImpl implements AppConfigService {
/***
* 新增修改
*
* @param appConfig
*/
public void addVertxConfig(VertxConfig vertxConfig) {
String vertxConfigKey = RedisConfig.VERTX_CONFIG_STRING_KEY;
String vertxConfigKey = RedisKeyConfig.VERTX_CONFIG_STRING_KEY;
redisTemplate.opsForValue().set(vertxConfigKey, JSONObject.toJSONString(vertxConfig));
// 发送redis队列,vertx处理
//String queue = RedisConfig.VETX_ENVIRONMENT_KEY+vertxEnvironment+":list";
// String queue = RedisKeyConfig.VETX_ENVIRONMENT_KEY+vertxEnvironment+":list";
}
}

View File

@ -0,0 +1,151 @@
package com.sf.vertx.utils;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* spring工具类 方便在非spring管理环境中获取bean
*
* @author ztzh
*/
@Component
public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationContextAware
{
/** Spring应用上下文环境 */
private static ConfigurableListableBeanFactory beanFactory;
private static ApplicationContext applicationContext;
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
{
SpringUtils.beanFactory = beanFactory;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
{
SpringUtils.applicationContext = applicationContext;
}
/**
* 获取对象
*
* @param name
* @return Object 一个以所给名字注册的bean的实例
* @throws org.springframework.beans.BeansException
*
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) throws BeansException
{
return (T) beanFactory.getBean(name);
}
public static <T> T getBean(String name, Class<T> classType) throws BeansException
{
return (T) beanFactory.getBean(name, classType);
}
/**
* 获取类型为requiredType的对象
*
* @param clz
* @return
* @throws org.springframework.beans.BeansException
*
*/
public static <T> T getBean(Class<T> clz) throws BeansException
{
T result = (T) beanFactory.getBean(clz);
return result;
}
/**
* 如果BeanFactory包含一个与所给名称匹配的bean定义则返回true
*
* @param name
* @return boolean
*/
public static boolean containsBean(String name)
{
return beanFactory.containsBean(name);
}
/**
* 判断以给定名字注册的bean定义是一个singleton还是一个prototype 如果与给定名字相应的bean定义没有被找到将会抛出一个异常NoSuchBeanDefinitionException
*
* @param name
* @return boolean
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
*
*/
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException
{
return beanFactory.isSingleton(name);
}
/**
* @param name
* @return Class 注册对象的类型
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
*
*/
public static Class<?> getType(String name) throws NoSuchBeanDefinitionException
{
return beanFactory.getType(name);
}
/**
* 如果给定的bean名字在bean定义中有别名则返回这些别名
*
* @param name
* @return
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
*
*/
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException
{
return beanFactory.getAliases(name);
}
/**
* 获取aop代理对象
*
* @param invoker
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T getAopProxy(T invoker)
{
return (T) AopContext.currentProxy();
}
/**
* 获取当前的环境配置无配置返回null
*
* @return 当前的环境配置
*/
public static String[] getActiveProfiles()
{
return applicationContext.getEnvironment().getActiveProfiles();
}
/**
* 获取配置文件中的值
*
* @param key 配置文件的key
* @return 当前的配置文件的值
*
*/
public static String getRequiredProperty(String key)
{
return applicationContext.getEnvironment().getRequiredProperty(key);
}
}