点燃创意激情,解锁无限可能——“我爱搞-52.ppt官网”等你来探索!

核心内容摘要

别让“日日操夜夜撸”掏空了你的底气:一场关于男人生命力的深度救赎
2023年免费安装“桶机大全”:开启你的数字娱乐新纪元!

9118禁解锁数字时代的安全边界与隐私迷局

兄弟们咱å�š Spring 项目的时候是ä¸�是总é�‡åˆ°è¿™äº›ç ´äº‹æ¯�个 Controller 里都è¦�写 Autowired UserService userService æ³¨å…¥ä¸€å¤§å † Service代ç �å�ˆä¹±å�ˆå†—ä½™æƒ³ç»Ÿä¸€åŠ ä¸ª 日志/异常处ç�† 得在æ¯�个 Service 方法里写一é��改起æ�¥è¦�ç–¯å�¶å°”还会手滑把 Service ç±»å��/方法å�� 写错编译ä¸�报错跑起æ�¥æ‰�出问题æ�’查å�Šå¤©ã€‚今天给大家分享个我自己写的 ServiceManager 组件用 Lambda æ��å®šè¿™äº›ç ´äº‹ —— ä¸�用手动注入 Service调用方法åƒ�写公å¼�ä¸€æ ·ç®€å�•还能自动缓存ã€�统一处ç�†å¼‚常新手也能秒懂秒用01组件能解决的å®�际问题先说说这组件能解决啥å®�é™…é—®é¢˜ä¸¾ä¸ªæ —å­�以å‰�咱调用用户查询æ�¥å�£å¾—这么写//

先注入Service Autowired private UserService userService; //

å†�调用方法 public SerResultUserDTO getUser(Long userId) { try { log.info(开始查用户ID{}, userId); UserDTO user userService.queryUser(userId); log.info(查询æˆ�功结æ�œ{}, user); return SerResult.success(user); } catch (Exception e) { log.error(查询失败, e); return SerResult.fail(查用户出错了); } }å�ˆæ˜¯æ³¨å…¥å�ˆæ˜¯æ—¥å¿—å�ˆæ˜¯ try-catch é‡�å¤�代ç �ä¸€å †ã€‚ç”¨äº† ServiceManager 之å��ç›´æ�¥å†™æˆ�è¿™æ ·public SerResultUserDTO getUser(Long userId) { // 一行æ��å®šä¼ æ–¹æ³•å�‚æ•°å…¶ä»–å…¨å¸®ä½ å�š return ServiceManager.call(UserService::queryUser, userId); }注入没了。日志组件自动打。异常组件自动处ç�†ã€‚爽ä¸�爽02ç»„ä»¶æ ¸å¿ƒé€»è¾‘å¤§ç™½è¯�拆解其å®�这组件就干了 3 ä»¶äº‹ä½ ä¼ ä¸ª Lambda比如 UserService::queryUser å®ƒå¸®ä½ æ‰¾åˆ°å¯¹åº”çš„ Service å®�例把找到的å®�例和方法缓存起æ�¥ä¸‹æ¬¡è°ƒç”¨æ›´å¿«ç»Ÿä¸€æ‰§è¡Œæ–¹æ³•顺便把日志ã€�异常处ç�†éƒ½åŒ…了。下é�¢å’±ä¸€æ­¥æ­¥æ�¥ä»£ç �éƒ½ç»™ä½ è´´å¥½å¤�制过å�»æ”¹æ”¹å°±èƒ½ç”¨ã€‚03å…ˆæ�­åŸºç¡€ — 需è¦�çš„ä¾�èµ–å’Œå·¥å…·ç±»é¦–å…ˆå¾—æœ‰å‡ ä¸ªå°�工具ä¸�用自己写直æ�¥å¤�制统一返å›�结æ�œç±»SerResultä¸�管调用æˆ�功还是失败都返å›�å�Œä¸€ä¸ªæ ¼å¼�å‰�端好处ç�†package org.pro.wwcx.ledger.common.dto; import lombok.Data; // æœ�务调用的统一返å›�结æ�œå‰�端拿到就知é�“是æˆ�功还是失败 Data publicclass SerResultT { privateint code; // 200æˆ�功500失败å‰�端一看就懂 private String msg; // æ��示信æ�¯æ¯”如“æ“�作æˆ�功â€�“查ä¸�到用户â€� private T data; // æˆ�功时返å›�的数æ�®æ¯”如用户信æ�¯ // æˆ�功的时候调用这个方法把数æ�®ä¼ è¿›å�» publicstatic T SerResultT success(T data) { SerResultT result new SerResult(); result.setCode(

; result.setMsg(æ“�作æˆ�功); result.setData(data); return result; } // å¤±è´¥çš„æ—¶å€™è°ƒç”¨è¿™ä¸ªæ–¹æ³•ä¼ é”™è¯¯ä¿¡æ�¯ publicstatic T SerResultT fail(String msg) { SerResultT result new SerResult(); result.setCode(

; result.setMsg(msg); result.setData(null); return result; } }Lambda è§£æ��工具LambdaUtilè¿™å·¥å…·æ˜¯æ ¸å¿ƒå¸®å’±ä»� Lambda 里 “扣â€� 出 Service ç±»å��和方法å��ä¸�用懂å�Ÿç�†å¤�制用就行package org.pro.wwcx.ledger.common.util; import java.io.Serializable; import java.lang.reflect.Method; import java.lang.invoke.SerializedLambda; // ä»�Lambda表达å¼�里拿Serviceä¿¡æ�¯çš„工具 publicclass LambdaUtil { // ä¼ ä¸ªLambdaè¿›æ�¥è¿”å›�它对应的“元数æ�®â€�比如哪个Service哪个方法 public static SerializedLambda valueOf(Serializable lambda) { if (lambda null) { thrownew IllegalArgumentException(Lambdaä¸�èƒ½ä¼ ç©º); } try { // å��射拿到Lambda里的éš�è—�方法ä¸�用管这行是咋å›�事 Method writeReplaceMethod lambda.getClass().getDeclaredMethod(writeReplace); writeReplaceMethod.setAccessible(true); return (SerializedLambda) writeReplaceMethod.invoke(lambda); } catch (Exception e) { thrownew RuntimeException(è§£æ��Lambda出错了, e); } } }Spring 工具类SpringUtil帮咱ä»� Spring 里拿 Service å®�例ä¸�用手动 Autowired 就是é� 它package org.pro.wwcx.ledger.common.util; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; // ä»�Spring里拿Bean的工具ä¸�用自己注入Service Component publicclass SpringUtil implements ApplicationContextAware { // Spring的上下文相当äº�“Bean仓库â€� privatestatic ApplicationContext applicationContext; // ä»�仓库里按类å�‹æ‹¿Bean比如拿UserServiceç±»å�‹çš„å®�例 publicstatic T T getBean(ClassT requiredType) { if (applicationContext null) { thrownew RuntimeException(Spring还没åˆ�始化好呢); } return applicationContext.getBean(requiredType); } // 下é�¢è¿™è¡Œæ˜¯Spring自动调用的ä¸�用管 Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringUtil.applicationContext applicationContext; } }函数æ�¥å�£SerialBiFunction这个是 Lambda çš„ “规矩â€�è§„å®šä¼ å�‚和返å›�å€¼çš„æ ¼å¼�å¤�制就行package org.pro.wwcx.ledger.common.resolver.anno; import java.io.Serializable; // 支æŒ�åº�列化的å�Œå�‚数函数æ�¥å�£Lambdaè¦�符å�ˆè¿™ä¸ªæ ¼å¼� public interface SerialBiFunctionT, U, R extends Serializable { // æ–¹æ³•æ ¼å¼�ä¼ å…¥TServiceå®�例和Uå�‚æ•°è¿”å›�R结æ�œ R apply(T t, U u); }å®�例æ�„建器InstBuilder帮咱快速创建对象的å°�工具ä¸�ç”¨å†™ä¸€å †set方法package org.pro.wwcx.ledger.common.resolver; // 快速创建对象的工具比如new ServiceExecutorå��ä¸�用一个个set值 public class InstBuilderT { privatefinal T target; // åˆ�始化è¦�创建的对象 private InstBuilder(ClassT clazz) { try { this.target clazz.getDeclaredConstructor().newInstance(); } catch (Exception e) { thrownew RuntimeException(创建对象失败, e); } } // é�™æ€�方法入å�£InstBuilder.of(ServiceExecutor.class) public static T InstBuilderT of(ClassT clazz) { returnnew InstBuilder(clazz); } // 链å¼�set值比如.set(ServiceExecutor::setParam, param) public V InstBuilderT set(SetterT, V setter, V value) { setter.set(target, value); returnthis; } // 最å��调用build()拿到对象 public T build() { return target; } // 定义setterçš„æ ¼å¼� FunctionalInterface public interface SetterT, V { void set(T target, V value); } }04æ ¸å¿ƒç»„ä»¶ — ServiceManagerè¿™æ˜¯å’±çš„ä¸»è§’æ‰€æœ‰é€»è¾‘éƒ½åœ¨è¿™æˆ‘ä¸€è¡Œè¡Œç»™ä½ è®²æ˜�白package org.pro.wwcx.ledger.common.servicer; import lombok.extern.slf4j.Slf4j; import org.pro.wwcx.ledger.common.dto.SerResult; import org.pro.wwcx.ledger.common.resolver.InstBuilder; import org.pro.wwcx.ledger.common.resolver.anno.SerialBiFunction; import org.pro.wwcx.ledger.common.util.LambdaUtil; import org.pro.wwcx.ledger.common.util.SpringUtil; import java.lang.invoke.SerializedLambda; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; // 日志注解能打日志 Slf4j public class ServiceManager { // 缓存åˆ�始化大å°�6666够咱用了ä¸�够å†�改 privatestaticfinalint INIT_COUNT 6666; // 缓存Lambda对应的Serviceä¿¡æ�¯key是Lambdavalue是Service元数æ�® privatestaticfinal MapSerialBiFunction?,?,?, LambdaMeta? CACHE_LAMBDA; // é�™æ€�代ç �å�—项目å�¯åŠ¨æ—¶å°±åˆ�始化缓存 static { CACHE_LAMBDA new ConcurrentHashMap(INIT_COUNT); } // 对外æ��ä¾›çš„è°ƒç”¨æ–¹æ³•ä¼ Lambda比如UserService::queryUserå’Œå�‚æ•°è¿”å›�结æ�œ SuppressWarnings(unchecked) public static T,U,R SerResultR call(SerialBiFunctionT,U,R fn, U param){ // 先检查Lambdaä¸�èƒ½ä¼ ç©º if (fn null) { return SerResult.fail(æœ�务函数ä¸�能为空); } //

�缓存拿Service信�有就直�用没有就解�并缓存 LambdaMetaT lambdaMeta (LambdaMetaT) CACHE_LAMBDA.computeIfAbsent(fn, k- { // 解�Lambda拿到Service�例�类�这些信� LambdaMetaT meta parseSerialFunction(fn); log.debug(缓存Service信�{}, meta.getServiceName()); return meta; }); //

创建执行器把Lambdaã€�å�‚æ•°ã€�Serviceä¿¡æ�¯ä¼ è¿›å�» ServiceExecutorT,U,R executor InstBuilder.of(ServiceExecutor.class) .set(ServiceExecutor::setServiceFn, fn) // ä¼ Lambda方法 .set(ServiceExecutor::setParam, param) // ä¼ å�‚æ•° .set(ServiceExecutor::setLambdaMeta, lambdaMeta) // ä¼ Serviceä¿¡æ�¯ .build(); // æ�„建执行器 //

执行方法返�结� return executor.callService(); } // 解�Lambda�Lambda里拿到Service类���例�方法� SuppressWarnings(unchecked) private static T, U, R LambdaMetaT parseSerialFunction(SerialBiFunctionT,U,R fn) { // 用LambdaUtil拿到Lambda的元数� SerializedLambda lambda LambdaUtil.valueOf(fn); // �装Service信�的对象 LambdaMetaT lambdaMeta new LambdaMeta(); //

解�Service类�Lambda里的类�是“com/example/UserService��改�“com.example.UserService� String tClassName lambda.getImplClass().replaceAll(/, .); try { //

拿到Service的Class对象比如UserService.class ClassT aClass (ClassT) Class.forName(tClassName); //

ä»�Spring里拿Serviceå®�例ä¸�用Autowired就是é� 这行 T inst SpringUtil.getBean(aClass); //

把信æ�¯å­˜åˆ°lambdaMeta里 lambdaMeta.setClazz(aClass); // å­˜Serviceçš„Class lambdaMeta.setInst(inst); // å­˜Serviceå®�例 lambdaMeta.setServiceName(lambda.getImplMethodName()); // 存方法å��比如queryUser } catch (ClassNotFoundException e) { // 找ä¸�到类就抛异常 thrownew RuntimeException(没找到Serviceç±» tClassName, e); } return lambdaMeta; } // å°�装Serviceä¿¡æ�¯çš„内部类存Classã€�å®�例ã€�方法å�� lombok.Data private staticclass LambdaMetaT { private ClassT clazz; // Serviceçš„Class比如UserService.class private T inst; // Serviceå®�例Spring里的Bean private String serviceName; // 方法å��比如queryUser } }05执行器 — ServiceExecutor这是帮咱统一执行方法ã€�打日志ã€�处ç�†å¼‚常的 “打工人â€�package org.pro.wwcx.ledger.common.servicer; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.pro.wwcx.ledger.common.dto.SerResult; import org.pro.wwcx.ledger.common.resolver.anno.SerialBiFunction; // 执行Service方法的类统一打日志ã€�处ç�†å¼‚常 Slf4j Setter publicclass ServiceExecutorT, U, R { private SerialBiFunctionT, U, R serviceFn; // è¦�执行的Lambda方法 private U param; // 方法å�‚æ•° private ServiceManager.LambdaMetaT lambdaMeta; // Serviceä¿¡æ�¯ // æ‰§è¡Œæ–¹æ³•çš„æ ¸å¿ƒé€»è¾‘ public SerResultR callService() { // 记录开始时间方便算耗时 long startTime System.currentTimeMillis(); String serviceName lambdaMeta.getClazz().getSimpleName(); // 比如UserService String methodName lambdaMeta.getServiceName(); // 比如queryUser log.info(开始调用{}çš„{}方法å�‚æ•°{}, serviceName, methodName, param); try { // 真正执行方法用Serviceå®�例调用Lambda方法 R result serviceFn.apply(lambdaMeta.getInst(), param); // 算耗时打æˆ�功日志 long costTime System.currentTimeMillis() - startTime; log.info(调用æˆ�功{}çš„{}方法耗时{}ms结æ�œ{}, serviceName, methodName, costTime, result); // è¿”å›�æˆ�功结æ�œ return SerResult.success(result); } catch (Exception e) { // 出错了就打错误日志返å›�失败结æ�œ long costTime System.currentTimeMillis() - startTime; log.error(调用失败{}çš„{}方法耗时{}ms, serviceName, methodName, costTime, e); return SerResult.fail(调用 serviceName çš„ methodName 方法失败 e.getMessage()); } } }06æ€�么用举个å®�际例å­�咱以用户查询和更新为例看 Controller 里æ€�么写先写个 Service正常写ä¸�用改package org.pro.wwcx.ledger.service; import org.pro.wwcx.ledger.dto.UserDTO; import org.pro.wwcx.ledger.dto.UserUpdateDTO; import org.springframework.stereotype.Service; // 正常的Service该咋写咋写 Service publicclass UserService { // æŸ¥ç”¨æˆ·æ ¹æ�®ID查 public UserDTO queryUser(Long userId) { // 这里模拟查数æ�®åº“å®�际项目里æ�¢JDBC/MyBatis UserDTO user new UserDTO(); user.setUserId(userId); user.setUserName(å¼ ä¸‰); user.setAge(

; return user; } // æ›´æ–°ç”¨æˆ·ä¼ ID和更新å�‚æ•° public Boolean updateUser(Long userId, UserUpdateDTO updateDTO) { // 这里模拟更新数æ�®åº“ log.info(更新用户{}的信æ�¯{}, userId, updateDTO); returntrue; // è¿”å›�æ›´æ–°æˆ�功 } }Controller 里调用é‡�点看å�˜åŒ–package org.pro.wwcx.ledger.controller; import org.pro.wwcx.ledger.common.dto.SerResult; import org.pro.wwcx.ledger.common.servicer.ServiceManager; import org.pro.wwcx.ledger.dto.UserDTO; import org.pro.wwcx.ledger.dto.UserUpdateDTO; import org.pro.wwcx.ledger.service.UserService; import org.springframework.web.bind.annotation.*; RestController RequestMapping(/user) publicclass UserController { // 查用户ä¸�用注入UserService一行æ��定 GetMapping(/{userId}) public SerResultUserDTO getUser(PathVariable Long userId) { // ç›´æ�¥ä¼ LambdaUserService::queryUserå’Œå�‚æ•°userId return ServiceManager.call(UserService::queryUser, userId); } // 更新用户å�Œæ ·ä¸�用注入 PutMapping(/{userId}) public SerResultBoolean updateUser( PathVariable Long userId, RequestBody UserUpdateDTO updateDTO) { // 这里è¦�注æ„�å› ä¸ºupdateUser有两个å�‚数所以è¦�显å¼�指定Lambdaç±»å�‹ return ServiceManager.call( (UserService service, UserUpdateDTO dto) - service.updateUser(userId, dto), updateDTO ); } }è·‘èµ·æ�¥çœ‹çœ‹æ•ˆæ�œæŸ¥ç”¨æˆ·çš„æ—¶å€™æ—¥å¿—会自动打开始调用UserServiceçš„queryUser方法å�‚æ•°1001 调用æˆ�功UserServiceçš„queryUser方法耗时5ms结æ�œUserDTO(userId1001, userNameå¼ ä¸‰, age

è¦�æ˜¯å‡ºé”™äº†æ¯”å¦‚ä¼ ä¸ªä¸�存在的用户 IDå�‡è®¾æ•°æ�®åº“查ä¸�到会抛异常日志会打错误信æ�¯è¿”å›�ç»™å‰�端的结æ�œæ˜¯{ code: 500, msg: 调用UserServiceçš„queryUser方法失败用户ä¸�存在, data: null }07这组件的好处总结一下ä¸�用å†�写 Autowired Controller 里干干净净å†�也ä¸�ç”¨æ³¨å…¥ä¸€å † Service统一日志 / 异常 æƒ³æ”¹æ—¥å¿—æ ¼å¼�ã€�åŠ æ�ƒé™�æ ¡éªŒå�ªéœ€è¦�改 ServiceExecutor ä¸�用改æ¯�个方法缓存优化 è§£æ��过的 Service ä¿¡æ�¯ä¼šç¼“存下次调用更快类å�‹å®‰å…¨ 写 Lambda 的时候方法å��错了编译就报错ä¸�用等到è¿�行æ‰�å�‘ç�°ã€‚08注æ„�事项é�¿å�‘指å�—JDK 版本 用 JDK8 å�Šä»¥ä¸ŠLambda 表达å¼�是 JDK8 æ‰�有的Service è¦�åŠ Service Spring æ‰�能扫æ��到ä¸�ç„¶ SpringUtil æ‹¿ä¸�到å®�例多å®�ç�°ç±»çš„æƒ…况 如æ�œä¸€ä¸ªæ�¥å�£æœ‰å¤šä¸ªå®�ç�°æ¯”如 UserService 有 UserServiceImpl1 å’Œ UserServiceImpl2 需è¦�在 SpringUtil é‡ŒåŠ æŒ‰å��ç§°æ‹¿ Bean 的方法。

三年在线观看免费完整版电视剧-三年在线观看免费完整版电视剧应用

百度百家号客服电话人工服务

123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123