更改solon的AOP为原生实现

This commit is contained in:
wind 2023-05-24 19:12:46 +08:00
parent a0efc2f166
commit 9f65661955
4 changed files with 62 additions and 144 deletions

View File

@ -1,7 +1,5 @@
package org.dromara.sms4j.solon; package org.dromara.sms4j.solon;
import org.dromara.sms4j.comm.annotation.Restricted;
import org.dromara.sms4j.solon.aop.AopAdvice;
import org.dromara.sms4j.solon.config.SmsAutowiredConfig; import org.dromara.sms4j.solon.config.SmsAutowiredConfig;
import org.noear.solon.core.AopContext; import org.noear.solon.core.AopContext;
import org.noear.solon.core.Plugin; import org.noear.solon.core.Plugin;
@ -13,6 +11,6 @@ public class XPluginImpl implements Plugin {
@Override @Override
public void start(AopContext context) throws Throwable { public void start(AopContext context) throws Throwable {
context.beanMake(SmsAutowiredConfig.class); context.beanMake(SmsAutowiredConfig.class);
context.beanAroundAdd(Restricted.class, new AopAdvice(context)); SmsAutowiredConfig.aopContext = context;
} }
} }

View File

@ -1,136 +0,0 @@
package org.dromara.sms4j.solon.aop;
import lombok.extern.slf4j.Slf4j;
import org.dromara.sms4j.comm.config.SmsConfig;
import org.dromara.sms4j.comm.exception.SmsBlendException;
import org.dromara.sms4j.comm.factory.BeanFactory;
import org.dromara.sms4j.comm.utils.SmsUtil;
import org.dromara.sms4j.comm.utils.TimeExpiredPoolCache;
import org.dromara.sms4j.solon.utils.RedisUtils;
import org.noear.solon.core.AopContext;
import org.noear.solon.core.aspect.Interceptor;
import org.noear.solon.core.aspect.Invocation;
import java.util.ArrayList;
@Slf4j
public class AopAdvice implements Interceptor {
private static final Long minTimer = 60 * 1000L;
private static final Long accTimer = 24 * 60 * 60 * 1000L;
private static final String REDIS_KEY = "sms:restricted:";
private SmsConfig config;
private RedisUtils redis;
public AopAdvice(AopContext context){
context.getBeanAsync(SmsConfig.class, bean->{
config = bean;
});
context.getBeanAsync(RedisUtils.class, bean->{
redis = bean;
});
}
@Override
public Object doIntercept(Invocation inv) throws Throwable {
if (BeanFactory.getSmsConfig().getRestricted()) {
String args = "";
ArrayList<String> argsList = new ArrayList<>();
try {
args = (String) inv.args()[0];
} catch (Exception e) {
for (Object o : (ArrayList<?>) inv.args()[0]) {
argsList.add((String) o);
}
}
SmsBlendException process = redisProcess(args);
if (process != null) {
throw process;
}
for (String f : argsList) {
SmsBlendException proce = null;
try {
proce = redisProcess(f);
} catch (Exception e) {
log.error(e.getMessage());
throw new RuntimeException(e);
}
if (proce != null) {
throw proce;
}
}
}
return inv.invoke();
}
private SmsBlendException process(String args) throws Exception {
TimeExpiredPoolCache instance = TimeExpiredPoolCache.getInstance();//缓存实例
Integer accountMax = config.getAccountMax();//每日最大发送量
Integer minuteMax = config.getMinuteMax();//每分钟最大发送量
if (SmsUtil.isNotEmpty(accountMax)) { //是否配置了每日限制
Integer i = instance.get(args + "max");
if (SmsUtil.isEmpty(i)) {
instance.put(args + "max", 1, accTimer);
} else if (i > accountMax) {
log.info("The phone:"+args +",number of short messages reached the maximum today");
return new SmsBlendException("The phone:"+args +",number of short messages reached the maximum today");
} else {
instance.put(args + "max", i + 1, accTimer);
}
}
if (SmsUtil.isNotEmpty(minuteMax)) { //是否配置了每分钟最大限制
Integer o = instance.get(args);
if (SmsUtil.isNotEmpty(o)) {
if (o < minuteMax) {
instance.put(args, o + 1, minTimer);
} else {
log.info("The phone:"+args +",number of short messages reached the maximum today");
return new SmsBlendException("The phone:", args + " Text messages are sent too often");
}
} else {
instance.put(args, 1, minTimer);
}
}
return null;
}
private SmsBlendException redisProcess(String args) throws Exception{
if (config.getRedisCache().equals("false")){
return process(args);
}
Integer accountMax = config.getAccountMax();//每日最大发送量
Integer minuteMax = config.getMinuteMax();//每分钟最大发送量
if (SmsUtil.isNotEmpty(accountMax)) { //是否配置了每日限制
Integer i = (Integer) redis.getByKey(REDIS_KEY+args + "max");
if (SmsUtil.isEmpty(i)) {
redis.setOrTime(REDIS_KEY+args + "max", 1,accTimer/1000);
} else if (i > accountMax) {
log.info("The phone:"+args +",number of short messages reached the maximum today");
return new SmsBlendException("The phone:"+args +",number of short messages reached the maximum today");
} else {
redis.setOrTime(REDIS_KEY+args + "max", i + 1,accTimer/1000);
}
}
if (SmsUtil.isNotEmpty(minuteMax)) { //是否配置了每分钟最大限制
Integer o = (Integer) redis.getByKey(REDIS_KEY+args);
if (SmsUtil.isNotEmpty(o)) {
if (o < minuteMax) {
redis.setOrTime(REDIS_KEY+args, o + 1,minTimer/1000);
} else {
log.info("The phone:"+args +",number of short messages reached the maximum today");
return new SmsBlendException("The phone:", args + " Text messages are sent too often");
}
} else {
redis.setOrTime(REDIS_KEY+args, 1,minTimer/1000);
}
}
return null;
}
}

View File

@ -0,0 +1,55 @@
package org.dromara.sms4j.solon.aop;
import lombok.extern.slf4j.Slf4j;
import org.dromara.sms4j.api.smsProxy.RestrictedProcess;
import org.dromara.sms4j.comm.config.SmsConfig;
import org.dromara.sms4j.comm.exception.SmsBlendException;
import org.dromara.sms4j.comm.utils.SmsUtil;
import org.dromara.sms4j.solon.utils.RedisUtils;
import org.noear.solon.core.AopContext;
@Slf4j
public class SolonRestrictedProcess extends RestrictedProcess {
private RedisUtils redis;
private static final Long minTimer = 60 * 1000L;
private static final Long accTimer = 24 * 60 * 60 * 1000L;
private static final String REDIS_KEY = "sms:restricted:";
public SolonRestrictedProcess(AopContext context){
context.getBeanAsync(RedisUtils.class, bean->{
redis = bean;
});
}
@Override
public SmsBlendException process(SmsConfig config, String args) throws Exception {
Integer accountMax = config.getAccountMax();//每日最大发送量
Integer minuteMax = config.getMinuteMax();//每分钟最大发送量
if (SmsUtil.isNotEmpty(accountMax)) { //是否配置了每日限制
Integer i = (Integer) redis.getByKey(REDIS_KEY+args + "max");
if (SmsUtil.isEmpty(i)) {
redis.setOrTime(REDIS_KEY+args + "max", 1,accTimer/1000);
} else if (i > accountMax) {
log.info("The phone:"+args +",number of short messages reached the maximum today");
return new SmsBlendException("The phone:"+args +",number of short messages reached the maximum today");
} else {
redis.setOrTime(REDIS_KEY+args + "max", i + 1,accTimer/1000);
}
}
if (SmsUtil.isNotEmpty(minuteMax)) { //是否配置了每分钟最大限制
Integer o = (Integer) redis.getByKey(REDIS_KEY+args);
if (SmsUtil.isNotEmpty(o)) {
if (o < minuteMax) {
redis.setOrTime(REDIS_KEY+args, o + 1,minTimer/1000);
} else {
log.info("The phone:"+args +",number of short messages reached the maximum today");
return new SmsBlendException("The phone:", args + " Text messages are sent too often");
}
} else {
redis.setOrTime(REDIS_KEY+args, 1,minTimer/1000);
}
}
return null;
}
}

View File

@ -1,6 +1,7 @@
package org.dromara.sms4j.solon.config; package org.dromara.sms4j.solon.config;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.sms4j.api.smsProxy.SmsInvocationHandler;
import org.dromara.sms4j.comm.config.SmsBanner; import org.dromara.sms4j.comm.config.SmsBanner;
import org.dromara.sms4j.comm.config.SmsConfig; import org.dromara.sms4j.comm.config.SmsConfig;
import org.dromara.sms4j.comm.config.SmsSqlConfig; import org.dromara.sms4j.comm.config.SmsSqlConfig;
@ -8,6 +9,7 @@ import org.dromara.sms4j.comm.constant.Constant;
import org.dromara.sms4j.comm.delayedTime.DelayedTime; import org.dromara.sms4j.comm.delayedTime.DelayedTime;
import org.dromara.sms4j.comm.factory.BeanFactory; import org.dromara.sms4j.comm.factory.BeanFactory;
import org.dromara.sms4j.core.SupplierSqlConfig; import org.dromara.sms4j.core.SupplierSqlConfig;
import org.dromara.sms4j.solon.aop.SolonRestrictedProcess;
import org.dromara.sms4j.solon.utils.RedisUtils; import org.dromara.sms4j.solon.utils.RedisUtils;
import org.noear.solon.Solon; import org.noear.solon.Solon;
import org.noear.solon.Utils; import org.noear.solon.Utils;
@ -15,6 +17,7 @@ import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Condition; import org.noear.solon.annotation.Condition;
import org.noear.solon.annotation.Configuration; import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject; import org.noear.solon.annotation.Inject;
import org.noear.solon.core.AopContext;
import org.noear.solon.core.Props; import org.noear.solon.core.Props;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
@ -24,6 +27,8 @@ import java.util.concurrent.Executor;
@Configuration @Configuration
public class SmsAutowiredConfig { public class SmsAutowiredConfig {
public static AopContext aopContext;
private <T> T injectObj(String prefix, T obj) { private <T> T injectObj(String prefix, T obj) {
//@Inject 只支持在字段参数类型上注入 //@Inject 只支持在字段参数类型上注入
Props props = Solon.cfg().getProp(prefix); Props props = Solon.cfg().getProp(prefix);
@ -76,14 +81,10 @@ public class SmsAutowiredConfig {
/* 如果配置中启用了redis则注入redis工具*/ /* 如果配置中启用了redis则注入redis工具*/
if (BeanFactory.getSmsConfig().getRedisCache()){ if (BeanFactory.getSmsConfig().getRedisCache()){
Solon.context().wrapAndPut(RedisUtils.class); Solon.context().wrapAndPut(RedisUtils.class);
SmsInvocationHandler.setRestrictedProcess(new SolonRestrictedProcess(aopContext));
log.debug("The redis cache is enabled for sms4j"); log.debug("The redis cache is enabled for sms4j");
} }
/* 如果启用了短信限制则注入AOP组件*/
if (BeanFactory.getSmsConfig().getRestricted()){
log.debug("SMS restriction is enabled");
}
//打印banner //打印banner
if (BeanFactory.getSmsConfig().getIsPrint()){ if (BeanFactory.getSmsConfig().getIsPrint()){
SmsBanner.PrintBanner(Constant.VERSION); SmsBanner.PrintBanner(Constant.VERSION);