Java语法

1、类属性定义
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ApiModel("命中统计")

2、字段定义
@ApiModelProperty(value = "融合单id", required = true)
@NotEmpty(message = "不能为空") 字符串类型
@NotNull(message = "dealResult-不可为空") 非字符串类型
@Min(value = 1, message = "取值为1或2")
@Max(value = 2, message = "取值为1或2")
@Size(max = 10, message = "单据类型不能超过10个")
@Length(max = 50, message = "需求方请求单号最长50")
@JsonAlias("Fcre_typeString")
@Range(min = 0, max = 1, message = "强制人工审核只能是0,1")

3、Applicaiont配置
@EnableFeignClients // 启用微服务调用能力
@EnableScheduling // 支持定时任务
@EnableCaching // 启用缓存功能
@EnableRetry // 提供重试机制

4、ApiController
@Api(tags = "触达相关接口")
@RequestMapping(value = "/submit", method = RequestMethod.POST)
@Valid @RequestBody
@RequestMapping(value = "/updateDbDispatchPeriod", method = RequestMethod.GET)
@RequestParam(required = false)
RequestParam

5、重试注解
@Retryable(value = RetryableBizException.class, maxAttempts = 3, backoff = @Backoff(delay = 100L, multiplier = 1))
value = RetryableBizException.class:指定当抛出RetryableBizException异常时触发重试机制
maxAttempts = 3:最多执行4次调用(1次初始+3次重试)
backoff = @Backoff(delay = 100L, multiplier = 1):固定100毫秒延迟,不采用指数退避
执行流程:
第一次调用 → 成功 → 返回结果
第一次调用 → 失败(RetryableBizException)→ 等待100ms → 第二次调用
第二次调用 → 失败 → 等待100ms → 第三次调用
第三次调用 → 失败 → 抛出异常(不再重试)

6、缓存注解
@Cacheable(cacheNames = "poolTag", key = "#root.methodName", unless = "#result == null")
public Map<String, Map<String, String>> getCkvPoolTagMap()
cacheNames = "poolTag":指定缓存名称为"poolTag"
key = "#root.methodName":使用完整方法名作为缓存键,例如getCkvPoolTagMap
unless = "#result == null":方法返回null时不进行缓存

@Configuration
@EnableCaching
public class CacheConfig {

@Bean
@Primary
public CacheManager guavaCacheManager() {
GuavaCacheManager cacheManager = new GuavaCacheManager();

cacheManager.setCacheBuilder(
CacheBuilder.newBuilder().
expireAfterWrite(60, TimeUnit.SECONDS). //写后过期策略:数据写入缓存后60秒自动失效
maximumSize(1000)); //最多缓存1k条目

return cacheManager;
}
}


7、分布式锁
//redis
RedisLockRegistry redisLockRegistry;
public Lock obtain(String lockKey) {
return redisLockRegistry.obtain(lockKey);
}
//zk
@Autowired
ZookeeperLockRegistry zookeeperLockRegistry;

@Override
public Lock obtain(String lockKey) {
// 1. 分桶计算:将任意锁键映射到1000范围的桶中
String realLockKey = String.valueOf(Math.abs(lockKey.hashCode()) % BUCKET_SIZE);

// 2. 日志记录:记录锁键到桶的映射关系,便于调试和监控
log.info("{}取到的桶为{}", lockKey, realLockKey);

// 3. 委托实现:使用Spring Integration的ZooKeeper锁注册器
return zookeeperLockRegistry.obtain(realLockKey);
}

Lock uinLock = null;
boolean lockFlag = false;
try {
uinLock = distributedLock.obtain(uinLockKey);
try {
lockFlag = uinLock.tryLock(100, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
log.info("tryLock distribute lock failed lockKey={}", uinLockKey);
return;
}

if (!lockFlag) {
log.info("tryLock distribute lock failed lockKey={}", uinLockKey);
return;
}
}catch (Exception e) {
throw e;
} finally {
try {
if (lockFlag) {
uinLock.unlock();
log.info("unlock distribute lock success lockKey={}", uinLockKey);
}
} catch (Exception e) {
log.error("uinLock.unlock() ex", e);
}
}

8、自定义注解
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface JobWait {
int sleepSecond() default 5;
}

@Component
@Aspect
@Slf4j
public class JobWaitAspect {

@Pointcut("@annotation(com.tenpay.risk.cdd.contact.logicsvr.core.infrastructure.common.retention.JobWait)")
public void jobWait() {
}

/**
* 接口调用前
*/
@Around(value = "jobWait()")
public Object jobWait(ProceedingJoinPoint joinPoint) throws Throwable {

try {
if (isWait()) {
log.debug("jobWait 1 sheep 2 sheep sleep");

// 获取方法签名
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
// 获取切入方法的对象
Method method = signature.getMethod();
// 获取方法上的Aop注解
JobWait jobWait = method.getAnnotation(JobWait.class);
Thread.sleep(jobWait.sleepSecond() * 1000);
return null;
} else {
return joinPoint.proceed();
}
} catch (Exception e) {
throw e;
}
}


9、Spring注解
@Component
@Repository
@Service
@Controller
@Profile(value = {"dev", "test", "uat", "prd", "inner", "CFT_FK-DEV", "CFT_FK-BVT", "CFT_FK-TEST", "CFT_FK-UAT", "CFT_FK-INNER", "CFT_FK-PRD"})
@Autowired//自动注入
@Qualifier("userDaoImpl")//指定特定的id的Bean对象来注入
@Qualifier("customObjectMapper")
@Resource("id"):等效于 @Autowired @Qualifier("id")的合用
@Transaction 事务
@Aspect 切面

//注入list
@Autowired
List<Validator> validators;

可选注入 @Autowired(required = false)

@Component
public class Validators {
@Autowired
List<Validator> validators;

public void validate(String email, String password, String name) {
for (var validator : this.validators) {
validator.validate(email, password, name);
}
}
}

public interface Validator {
void validate(String email, String password, String name);
}

@Component
@Order(1)
public class EmailValidator implements Validator {
public void validate(String email, String password, String name) {
if (!email.matches("^[a-z0-9]+\\@[a-z0-9]+\\.[a-z]{2,10}$")) {
throw new IllegalArgumentException("invalid email: " + email);
}
}
}

@Component
@Order(2)
public class PasswordValidator implements Validator {
public void validate(String email, String password, String name) {
if (!password.matches("^.{6,20}$")) {
throw new IllegalArgumentException("invalid password");
}
}
}


//指定路径
@Value("classpath:/logo.txt")
private Resource resource;


@Configuration
@ComponentScan
@PropertySource("app.properties") // 表示读取classpath的app.properties
public class AppConfig {
@Value("${app.zone:Z}")
String zoneId;

@Bean
ZoneId createZoneId() {
return ZoneId.of(zoneId);
}
}

@Component
public class SmtpConfig {
@Value("${smtp.host}")
private String host;

@Value("${smtp.port:25}")
private int port;

public String getHost() {
return host;
}

public int getPort() {
return port;
}
}

@Component
public class MailService {
@Value("#{smtpConfig.host}")
private String smtpHost;

@Value("#{smtpConfig.port}")
private int smtpPort;
}


10、限流语法
@Limit(maxThreshold = 1, fallbackClass = CddOpController.class,
fallbackMethod = "qryCddAuditNcInfoFallback", limitByGroupParameterNames = "kf")


11、获取java当前环境
SpringContextUtil.isSomeEnv

12、加密算法
DigestUtils.sha1Hex

13、java泛型用法
protected <T extends BiArgument> T buildCommonArgument(String token, String username, T arg) {

14、Map,Filter
long retCode = Optional.ofNullable(result)
.map(BiResult::getCode)
.filter(StringUtils::isNotBlank)
.map(Long::parseLong)
.orElse(ErrorCodeConstant.EXECUTE_FAILURE.getCode());
String retMsg = Optional.ofNullable(result)
.map(BiResult::getMessage)
.filter(StringUtils::isNotBlank)
.orElse(ErrorCodeConstant.EXECUTE_FAILURE.getMsg());

15、Java异常类
NullPointerException
IllegalArgumentException
RuntimeException
UnsupportedOperationException

16、事务
@Transactional(rollbackFor = Exception.class)


17、java枚举
//Java枚举
public enum EnumLimitTreatment {
/**
* 处置方案
*/
IGNORE(0, "无需处理"),
OP_RETRY(1, "业务方重试补偿"),
DEVELOP_RETRY(2, "技术侧技术手段自动补偿"),
DEVELOP_INTERVENTION(3, "技术侧人工介入处理")
;
/**
* 编号
*/
private final Integer code;

/**
* 说明
*/
private final String name;

EnumLimitTreatment(Integer code, String name) {
this.code = code;
this.name = name;
}

public Integer getCode() {
return code;
}

public String getName() {
return name;
}

public static EnumLimitTreatment getByCode(Integer code) {
return Arrays.stream(EnumLimitTreatment.values())
.filter(t -> t.getCode().equals(code))
.findFirst()
.orElse(null);
}
}

18、切面
// https://blog.csdn.net/u011047968/article/details/104402079
//Java切面编程 鉴权
@Slf4j
@Aspect
@Component
public class PayAspect {

@Value("${pay.appKey}")
private String payAppKey;

@Value("${pay.appId}")
private String appId;

@Pointcut("execution(public * com.tenpay.risk.cpl.proxy.broker.core.controller.PayController.*(..))")
public void payControllerPt() {
}

@Before("payControllerPt()")
public void payCheck() {
// 针对支付接口进行鉴权
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
.getRequest();
String caller = request.getHeader("Caller");
if (!appId.equals(caller)) {
log.error("not privilege to invoke pay api, appId={}", appId);
throw new ServiceFailException(ErrorCodeConstant.PRIVILEGE_AUTH_ERROR);
}
String appId = request.getHeader("AppId");
String token = request.getHeader("Token");
String requestId = request.getHeader("RequestId");
String ownToken = payAppKey + appId + requestId;
if (!DigestUtils.md5Hex(ownToken).toLowerCase().equals(token)) {
log.error("not privilege to invoke pay api, appId={}", appId);
throw new ServiceFailException(ErrorCodeConstant.PRIVILEGE_AUTH_ERROR);
}
}
}

//流量限制
@Slf4j
@Aspect
@Component
public class RateLimitAspect {

/**
* 通用限流
*/
private RateLimiter common = RateLimiter.create(150);

/**
* 流水限流
*/
private RateLimiter capitalFlow = RateLimiter.create(10);

@Pointcut("execution(public * com.tenpay.risk.cpl.proxy.broker.core.controller..*.*(..))")
public void commonRateLimitPt(){}

@Before("commonRateLimitPt()")
public void commonRateLimit() {
if (!common.tryAcquire()) {
throw new ServiceFailException(ErrorCodeConstant.API_RATE_LIMIT_ERROR);
}
}

@Pointcut("execution(public * com.tenpay.risk.cpl.proxy.broker.core.controller.BusinessController.*(..))")
public void capitalFlowRateLimitPt(){}

@Before("capitalFlowRateLimitPt()")
public void capitalFlowRateLimit() {
if (!capitalFlow.tryAcquire()) {
throw new ServiceFailException(ErrorCodeConstant.CAPITAL_FLOW_API_RATE_LIMIT_ERROR);
}
}

}

19.多线程
ExecutorService executorService = Executors.newFixedThreadPool(nThreads);

for (TCddUinCacheRelieveCheck item : waittingRecords) {
Future<?> future = executorService.submit(() -> {
try {
// 处理每个item的逻辑
checkUnRelieveUinCKVDetail(item);
}catch (Exception e) {
log.error("处理item失败,item信息:{},错误信息:{}", item, e.getMessage(), e); // 记录异常信息
}
});
}

executorService.shutdown(); // 关闭线程池
try {
executorService.awaitTermination(30, TimeUnit.MINUTES); // 等待所有任务完成
} catch (InterruptedException e) {
log.error("线程池关闭时发生异常:{}", e.getMessage(), e); // 记录错误信息
}


private final ConcurrentHashMap<String, Set<String>> classFieldMap = new ConcurrentHashMap<>();

private final ImmutableMap<String, String> additionClassDependency =
new ImmutableMap.Builder<String, String>()
.put("BUSINESS_LICENSE_QUERY_INFO", "BUSINESS_LICENSE")
.put("BUSINESS_LICENSE_CANCEL_REVOKE_INFO", "BUSINESS_LICENSE")
.put("ENTERPRISE_REPRESENTATIVE", "LEGAL_PERSON_CERTIFICATE")
.put("UBO_QUERY_INFO", "UBO")
.build();

20、状态机更新
public int updateStatus(String id, Integer statusBefore, Integer statusAfter)

21、ApplicationRunner
应用启动后初始化定时任务配置

public static final BlockingQueue<ImmutablePair<InterceptVerifyRequest, ResponseEntity<InterceptVerifyResponse>>> VERIFY_QUEUE
= new LinkedBlockingQueue<>();

@Override
public void run(ApplicationArguments args) throws Exception {

new Thread(() -> {
while (true) {
try {
String uin = notifyAppService.takeRecord();
if (MixAll.isNotEmpty(uin)) {
log.info("cddNotifyTask take uin={}", uin);
notifyAppLockWrapper.execCddNotifyTask(uin);
}
} catch (Exception e) {
log.error("CddDemandTaskJob run thread ex", e);
}
}

}).start();
}

22、事前,事中,事后思想
@Service
public class QqAuditNotifyServiceImpl extends CddNotifyDomainService {

@Override
public boolean match(CddNotifyRecord cddNotifyRecord) {
return (CddNotifyType.AUDIT_FAILED.getCode() == cddNotifyRecord.getNotifyType())
&& MixAll.isQqAcc(cddNotifyRecord.getUin());
}

@Override
public CddNotifyRecord sendBefore(CddNotifyRecord cddNotifyRecord) {
return super.sendBefore(cddNotifyRecord);
}

@Override
public CddNotifyRecord send(CddNotifyRecord cddNotifyRecord) {
return super.send(cddNotifyRecord);
}

@Override
public CddNotifyRecord sendAfter(CddNotifyRecord cddNotifyRecord) {
return super.sendAfter(cddNotifyRecord);
}
}

23、java判断null方法
Objects.requireNonNull
Objects.nonNull(frontImgBytes)
Base64.getEncoder().encodeToString(backImgBytes)

24、内存锁
public static final BlockingQueue<String> RECORD_QUEUE = new LinkedBlockingQueue<>();
public static Set<String> RECORD_SET = new HashSet<>();

public static ReentrantLock lock = new ReentrantLock();


public void addRecordQueue(CddNotifyRecord cddNotifyRecord) {
if (cddNotifyRecord == null) {
return;
}

CddNotifyJob.lock.lock();
try {
if (!CddNotifyJob.RECORD_SET.contains(cddNotifyRecord.getUin())) {
CddNotifyJob.RECORD_QUEUE.add(cddNotifyRecord.getUin());
CddNotifyJob.RECORD_SET.add(cddNotifyRecord.getUin());
log.info("addTaskToQueue id={}, TASK_QUEUE.SIZE={}, TASK_SET.SIZE={}", cddNotifyRecord.getId(),
CddNotifyJob.RECORD_QUEUE.size(), CddNotifyJob.RECORD_SET.size());
}
} catch (Exception e) {
log.error("addTaskToQueue ex", e);
} finally {
CddNotifyJob.lock.unlock();
}
}


public String takeRecordAcc() {
String account = null;

CddNotifyJob.lock.lock();
try {
account = CddNotifyJob.RECORD_QUEUE.poll();
if (account != null) {
CddNotifyJob.RECORD_SET.remove(account);
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
CddNotifyJob.lock.unlock();
}

return account;
}

 

posted @ 2026-06-16 14:49  yuxuan0802  阅读(4)  评论(0)    收藏  举报