范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

自定义注解妙用,一行代码搞定用户操作日志记录,你学会了吗?

  1.简介
  我在使用spring完成项目的时候需要完成记录日志,我开始以为Spring 的AOP功能,就可以轻松解决,半个小时都不用,可是经过一番了解过后,发现一般的日志记录,只能记录一些简单的操作,例如表名、表名称等记录不到。
  这个时侯就用到了自定义注解,把想要记录的内容放在注解中,通过切入点来获取到注解参数,然后将参数插入数据库记录 2.Spring AOP
  对于Spring Aop的基本介绍大家可以看看:
  https://blog.csdn.net/yjt520557/article/details/84833508
  这里是为了方便大家理解如何实现给大家解释一下 2.1.关于Spring AOP的一些术语切面(Aspect) :在Spring AOP中,切面可以使用通用类或者在普通类中以@Aspect 注解(@AspectJ风格)来实现连接点(Joinpoint) :在Spring AOP中一个连接点代表一个方法的执行通知(Advice) :在切面的某个特定的连接点(Joinpoint)上执行的动作。通知有各种类型,其中包括"around"、"before"和"after"等通知。许多AOP框架,包括Spring,都是以拦截器做通知模型, 并维护一个以连接点为中心的拦截器链切入点(Pointcut) :定义出一个或一组方法,当执行这些方法时可产生通知,Spring缺省使用AspectJ切入点语法。通知类型前置通知(@Before) :在某连接点(join point)之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常)返回后通知(@AfterReturning) :在某连接点(join point)正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回抛出异常后通知(@AfterThrowing) :方法抛出异常退出时执行的通知后通知(@After) :当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)环绕通知(@Around) :包围一个连接点(join point)的通知,如方法调用。这是最强大的一种通知类型,环绕通知可以在方法调用前后完成自定义的行为,它也会选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常来结束执行2.2.Spring AOP配置有两种风格:XML风格 = 采用声明形式实现Spring AOP AspectJ风格 = 采用注解形式实现Spring AOP 3.首先自定义注解
  定义一个日志描述和一个表名这里根据需要自定义注解 package com.ywj.log;   import java.lang.annotation.*;   /**  * ClassName Crmlog  * AOP日志记录 自定义注解类  */ @Target({ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface SystemCrmlog {     /**      * 日志描述      * 对于什么表格进行了什么操作      */     String description()  default "";       /**      * 操作了的表名      * @return      */     String  tableName() default ""; } 3.1.定义切面类,从切入点获取注解信息保存到数据库
  对于一些可能碰到的问题我在方法的注释里都有解决办法,大家注意一下,这里我对于方法报错也有处理方法
  这里是对于切面类里使用到的两个类解释:
  AspectJ使用 org.aspectj.lang.JoinPoint  接口表示目标类连接点对象,如果是环绕增强时,使用org.aspectj.lang.ProceedingJoinPoint  表示连接点对象,该类是JoinPoint的子接口。任何一个增强方法都可以通过将第一个入参声明为JoinPoint访问到连接点上下文的信息。我们先来了解一下这两个接口的主要方法:1)JoinPointjava.lang.Object[] getArgs()  :获取连接点方法运行时的入参列表;Signature getSignature()   :获取连接点的方法签名对象;java.lang.Object getTarget()   :获取连接点所在的目标对象;java.lang.Object getThis()   :获取代理对象本身;2)ProceedingJoinPoint
  ProceedingJoinPoint继承JoinPoint子接口,它新增了两个用于执行连接点方法的方法: java.lang.Object proceed() throws java.lang.Throwable  :通过反射执行目标对象的连接点处的方法;java.lang.Object proceed(java.lang.Object[] args) throws java.lang.Throwable  :通过反射执行目标对象连接点处的方法,不过使用新的入参替换原来的入参。package com.ywj.log;     import com.fasterxml.jackson.databind.ObjectMapper; import com.ywj.log.biz.Sys_logBiz; import com.ywj.log.dao.Sys_logDao; import com.ywj.login.biz.Sys_UserBiz; import com.ywj.login.dao.Sys_UserDao; import com.ywj.login.dao.Sys_righDao; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes;   import javax.servlet.http.HttpServletRequest; import java.lang.reflect.Method; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.Map;     /**  * @ClassName SystemLogAspect  * @Author Administrator  * @Describe  定义切入面类  */ @Aspect @Component public class SystemLogAspect {         /**      * 注解Pointcut切入点      * 定义出一个或一组方法,当执行这些方法时可产生通知      * 指向你的切面类方法      * 由于这里使用了自定义注解所以指向你的自定义注解      */     @Pointcut("@annotation(com.ywj.log.SystemCrmlog)")     public void crmAspect() {     }         /**      *抛出异常后通知(@AfterThrowing):方法抛出异常退出时执行的通知      * 注意在这里不能使用ProceedingJoinPoint      * 不然会报错ProceedingJoinPoint is only supported for around advice      * throwing注解为错误信息      * @param joinPoint      * @param ex      */     @AfterThrowing(value="crmAspect()", throwing="ex")     public void afterThrowingMethod(JoinPoint joinPoint, Exception ex) throws Exception {         HttpServletRequest httpServletRequest = getHttpServletRequest();         //获取管理员用户信息         WebUtil webUtil = new WebUtil();         Map user = webUtil.getUser(httpServletRequest);         CrmLogMessage log=new CrmLogMessage();         //获取需要的信息         String context=getServiceMthodDescription(joinPoint);         String usr_name="";         String rolename="";         if(user!=null){             usr_name = user.get("usr_name").toString();             rolename=user.get("rolename").toString();         }         //管理员姓名         log.setUserName(usr_name);         //角色名         log.setUserRole(rolename);         //日志信息         log.setContent(usr_name+context);         //设置参数集合         log.setRemarks(getServiceMthodParams(joinPoint));         //设置表名         log.setTableName(getServiceMthodTableName(joinPoint));         //操作时间         SimpleDateFormat sif=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");         log.setDateTime(sif.format(new Date()));         //设置ip地址         log.setIp(httpServletRequest.getRemoteAddr());         //设置请求地址         log.setRequestUrl(httpServletRequest.getRequestURI());         //执行结果         log.setResult("执行失败");         //错误信息         log.setExString(ex.getMessage());         //将数据保存到数据库         Sys_logDao sysLogDao=new Sys_logDao();         sysLogDao.addSys_log(log);     }         /**      * 返回后通知(@AfterReturning):在某连接点(joinpoint)      * 正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回      * 方法执行完毕之后      * 注意在这里不能使用ProceedingJoinPoint      * 不然会报错ProceedingJoinPoint is only supported for around advice      * crmAspect()指向需要控制的方法      *  returning  注解返回值      * @param joinPoint      * @param returnValue  返回值      * @throws Exception      */     @AfterReturning(value = "crmAspect()",returning = "returnValue")     public  void doCrmLog(JoinPoint joinPoint,Object returnValue) throws Exception {         HttpServletRequest httpServletRequest = getHttpServletRequest();         //获取管理员用户信息         WebUtil webUtil = new WebUtil();         Map user = webUtil.getUser(httpServletRequest);         CrmLogMessage log=new CrmLogMessage();         String context=getServiceMthodDescription(joinPoint);           String usr_name="";         String rolename="";         if(user!=null){          usr_name = user.get("usr_name").toString();          rolename=user.get("rolename").toString();         }         //管理员姓名         log.setUserName(usr_name);         //角色名         log.setUserRole(rolename);         //日志信息         log.setContent(usr_name+context);         //设置参数集合         log.setRemarks(getServiceMthodParams(joinPoint));         //设置表名         log.setTableName(getServiceMthodTableName(joinPoint));         //操作时间         SimpleDateFormat sif=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");         log.setDateTime(sif.format(new Date()));         //设置ip地址         log.setIp(httpServletRequest.getRemoteAddr());         //设置请求地址         log.setRequestUrl(httpServletRequest.getRequestURI());         if(returnValue!=null){            if(returnValue instanceof List){                List ls= (List) returnValue;                if(ls.size()>0){                    log.setResult("执行成功");                }else{                    log.setResult("执行成功");                }            }else if(returnValue instanceof Boolean){                Boolean falg= (Boolean) returnValue;                if(falg){                    log.setResult("执行成功");                }else{                    log.setResult("执行失败");                }            }else if(returnValue instanceof Integer){                Integer i= (Integer) returnValue;                if(i>0){                    log.setResult("执行成功");                }else{                    log.setResult("执行失败");                }            }else{                log.setResult("执行成功");            }           }         //将数据保存到数据库         Sys_logDao sysLogDao=new Sys_logDao();         sysLogDao.addSys_log(log);     }         /**      *获取自定义注解里的日志描述      * @param joinPoint      * @return 返回注解里面的日志描述      * @throws Exception      */     private String getServiceMthodDescription(JoinPoint joinPoint)             throws Exception {         //类名         String targetName = joinPoint.getTarget().getClass().getName();         //方法名         String methodName = joinPoint.getSignature().getName();         //参数         Object[] arguments = joinPoint.getArgs();         //通过反射获取示例对象         Class targetClass = Class.forName(targetName);         //通过实例对象方法数组         Method[] methods = targetClass.getMethods();         String description = "";         for(Method method : methods) {             //判断方法名是不是一样             if(method.getName().equals(methodName)) {                 //对比参数数组的长度                 Class[] clazzs = method.getParameterTypes();                 if(clazzs.length == arguments.length) {                     //获取注解里的日志信息                     description = method.getAnnotation(SystemCrmlog.class).description();                     break;                 }             }         }         return description;     }       /**      *获取自定义注解里的表名      * @param joinPoint      * @return 返回注解里的表名字      * @throws Exception      */     private String getServiceMthodTableName(JoinPoint joinPoint)             throws Exception {         //类名         String targetName = joinPoint.getTarget().getClass().getName();         //方法名         String methodName = joinPoint.getSignature().getName();         //参数         Object[] arguments = joinPoint.getArgs();         //通过反射获取示例对象         Class targetClass = Class.forName(targetName);         //通过实例对象方法数组         Method[] methods = targetClass.getMethods();         //表名         String tableName = "";         for (Method method : methods) {             //判断方法名是不是一样             if (method.getName().equals(methodName)) {                 //对比参数数组的长度                 Class[] clazzs = method.getParameterTypes();                 if (clazzs.length == arguments.length) {                     //获取注解里的表名                     tableName = method.getAnnotation(SystemCrmlog.class).tableName();                     break;                 }             }         }         return tableName;     }       /**      * 获取json格式的参数用于存储到数据库中      * @param joinPoint      * @return      * @throws Exception      */     private String getServiceMthodParams(JoinPoint joinPoint)             throws Exception {         Object[] arguments = joinPoint.getArgs();         ObjectMapper om=new ObjectMapper();         return om.writeValueAsString(arguments);     }       /**      * 获取当前的request      * 这里如果报空指针异常是因为单独使用spring获取request      * 需要在配置文件里添加监听      *       *       * org.springframework.web.context.request.RequestContextListener      *       *       * @return      */     public HttpServletRequest getHttpServletRequest(){         RequestAttributes ra = RequestContextHolder.getRequestAttributes();         ServletRequestAttributes sra = (ServletRequestAttributes)ra;         HttpServletRequest request = sra.getRequest();         return request;     }   }
  每个切面传递的数据的都不一样,最终决定,获取切面的所有参数,转成json字符串,保存到数据库中。 相关类:
  日志信息类 package com.ywj.log;   /**  * @ClassName CrmLogMessage  * @Author Administrator  * @Describe 数据库日志类  */ public class CrmLogMessage {     private Integer logid;//日志id     private String UserName;//管理员姓名     private String UserRole;//管理员角色     private String Content;//日志描述     private String Remarks;//参数集合     private String TableName;//表格名称     private String DateTime;//操作时间     private String resultValue;//返回值     private String ip;//ip地址     private String  requestUrl;//请求地址     private String result;//操作结果     private  String ExString;//错误信息       public CrmLogMessage() {     }       @Override     public String toString() {         return "CrmLogMessage{" +                 "logid=" + logid +                 ", UserName="" + UserName + """ +                 ", UserRole="" + UserRole + """ +                 ", Content="" + Content + """ +                 ", Remarks="" + Remarks + """ +                 ", TableName="" + TableName + """ +                 ", DateTime="" + DateTime + """ +                 ", resultValue="" + resultValue + """ +                 ", ip="" + ip + """ +                 ", requestUrl="" + requestUrl + """ +                 ", result="" + result + """ +                 ", ExString="" + ExString + """ +                 "}";     }       public CrmLogMessage(Integer logid, String userName, String userRole, String content, String remarks, String tableName, String dateTime, String resultValue, String ip, String requestUrl, String result, String exString) {         this.logid = logid;         UserName = userName;         UserRole = userRole;         Content = content;         Remarks = remarks;         TableName = tableName;         DateTime = dateTime;         this.resultValue = resultValue;         this.ip = ip;         this.requestUrl = requestUrl;         this.result = result;         ExString = exString;     }       public String getExString() {         return ExString;     }       public void setExString(String exString) {         ExString = exString;     }       public Integer getLogid() {         return logid;     }       public void setLogid(Integer logid) {         this.logid = logid;     }       public String getUserName() {         return UserName;     }       public void setUserName(String userName) {         UserName = userName;     }       public String getUserRole() {         return UserRole;     }       public void setUserRole(String userRole) {         UserRole = userRole;     }       public String getContent() {         return Content;     }       public void setContent(String content) {         Content = content;     }       public String getRemarks() {         return Remarks;     }       public void setRemarks(String remarks) {         Remarks = remarks;     }       public String getTableName() {         return TableName;     }       public void setTableName(String tableName) {         TableName = tableName;     }       public String getDateTime() {         return DateTime;     }       public void setDateTime(String dateTime) {         DateTime = dateTime;     }       public String getResultValue() {         return resultValue;     }       public void setResultValue(String resultValue) {         this.resultValue = resultValue;     }       public String getIp() {         return ip;     }       public void setIp(String ip) {         this.ip = ip;     }       public String getRequestUrl() {         return requestUrl;     }       public void setRequestUrl(String requestUrl) {         this.requestUrl = requestUrl;     }       public String getResult() {         return result;     }       public void setResult(String result) {         this.result = result;     } }
  用来获取登录用户信息的帮助类: package com.ywj.log;   import com.base.web.BaseAction;   import javax.servlet.http.HttpServletRequest; import java.util.Map;   /**  * @ClassName WebUtil  * @Author Administrator  * @Describe  日志帮助类 用来获取session中的用户信息来存入数据库  */ public class WebUtil  {         /**      * 从session中获取到用户对象      * @return      */     public Map   getUser(HttpServletRequest request){         Map attribute=null;         if(request!=null){         Object user = request.getSession().getAttribute(Constans.USER_KEY);       attribute = (Map) user;}     return attribute; }      }
  在你的spring-context.xml中配置                             
  然后在你需要记录的方法上加上注解 @SystemCrmlog(description = "进行了登录操作",tableName =Constans.USER_TABLENAME)
  效果这里表名使用了常量类
  对于一些表的信息可以写一个常量类
  然后执行登录操作数据库记录为:

武汉求财神的归元寺香客爆满人山人海,求平安的古德寺则遭冷落上图位于武汉市汉阳区翠微街归元寺路20号的归元寺。归元寺1658年由浙江僧人白光主峰来此创建。取名归元是出自佛经楞严经里的归元无二路,方便有多门而来。归元即归真,就是超出生灭之界,孩子,不要做胆小鬼今天是2023年1月18日,从今天起,我决定入驻头条,开始我的抄书生涯。育儿对于我来说,是一件头疼且痛苦的事。自从有了二胎儿子,我的生活不再有安宁,为培养儿子,也为像我一样有着育儿孩子的脾胃很重要,妈妈们要注意婴儿脾胃功能六个月以后能够逐渐发育,所以添加辅食大多在六个月之后,提前添加辅食会增加脾胃负担。在宝宝三岁的时候脾胃发育好,但仍要注意要吃容易消化的食物,少吃高热量,寒凉的食物。高热正常结婚后会想要小孩吗,如果不想要会因为有补助生娃吗头条创作挑战赛今天听到很地方政府出台了关于生二胎,三胎的政策鼓励办法。有的是每月补助六百块钱,有的是给孩子提供各种上学的便利等等各种优惠政策。为了鼓励大家生育,政府可以说给出了绝对女孩出现早恋家长如何处理?聪明的家长这样做!现阶段的孩子随着年龄的增长,会变得逐渐早熟,所以在孩子的成长过程中,必然会出现早恋的现象。其实早恋不可怕,家长正确的引导以及提升孩子的觉悟是关键。女孩出现早恋家长如何处理?家长可以应试教育让孩子对确定性高度依赖,不想让他迷上标准答案该咋办?我的教育观,经历过两次比较大的升级。高中时代起,我就对应试教育深恶痛绝,认为这是扼杀人性自由光辉的魔鬼!我本人深受其害,苦不堪言,又无能为力,只能在作文里不断讽刺这种教育体制给一代过年吃得太油腻?5款节后清肠掉秤食谱来啦,速速收藏!今日初八,开门复工啦过年吃得丰盛但难免油腻长假结束后一定要来几顿清肠去火的菜肴调理一下补充膳食纤维保证营养均衡摄入快和小编一起动手学起来吧减脂版虾滑冒菜食材准备魔芋乌冬面150g,LOL最脏套路你见过几个?大家好,我又来了。目前联盟上分是越来越难了,时不时遇到一些骚套路,属实把小编我恶心坏了,什么卢娜上单老司机偷家青钢影加加里奥这都是众所周知了,今天分析一下那些我遇到的奇怪骚套路。方如龙维新PC配置要求公布!人中之龙维新极硬件需求一览PS主机动作冒险游戏如龙维新极即将登陆PC平台,今日官方公布了它的PC配置要求。该游戏最低需要i53470GTX9608GB内存即可运行。一起来看看吧最低配置(1080p低画质30写一首诗歌疗伤,我听见水鸟起飞的声音春节已过,写一首诗歌,致敬过去,喜迎将来,也算是疗伤文,2022心身俱疲,做个切割,希望2023大展宏图,顺风顺水。我听见水鸟起飞的声音文李子树下下雪了,昨天还是阳光明媚就在昨天,名记曝光足协音频!酒后口吐芬芳为领导出头,疑似借媒体打压派系从足协秘书长刘奕副秘书长陈永亮被带走,到国脚吴兴涵被曝丑闻,再到武汉长江退出解散,中国足球界在春节期间负面事件频发。而就当春节假期即将结束时,一条疑似足协官员酒后内斗互掐口吐芬芳的
詹姆斯无意中透露退役时间,比起总冠军,父子同场才是他的梦想就在近日,詹姆斯夫妻在接受媒体采访时,关于布朗尼的未来夫妻俩给出不同看法。萨瓦娜说只要布朗尼过得开心就行。而詹姆斯却说我想布朗尼进入NBA,能和我同场竞技。詹姆斯的一席话无意中透露曾讽球迷吃方便面穿拖鞋的杨旭,2个赛季0球0助,仍赚顶薪1320万今年34岁的国脚杨旭在最近2个赛季中,个人数据惨淡到了极点连续两个赛季0进球0助攻!不过,反差极大得令人侧目的是,杨旭却在这两个赛季里,仍然能拿到中超顶薪税后年薪660万,相当于1我们所处的世界是真实的嘛?宇宙之外有人看我们嘛?人是否是外星人降临到地球星海的对面是否有和我们一样的人类对于深海的鱼类而言,海水与深海生物就是它们的世界,它们不会知道在海洋之外,还有陆地的存在,更不会知道陆网友直言北慕登顶对面澜是演员,赛后点进主页,澜是KPL第一打野王者荣耀S25赛季也走向了尾声,对于许多玩家们来说,最瞩目的无疑是巅峰赛状况,而近期的巅峰赛本来玩家们以为是小锦儿与微凉的战争,毕竟两个人这个赛季一直在冲巅峰赛,可是老野王北慕赛季王者荣耀新赛季马上到来,真心希望天美能引进精准匹配机制哈喽大家好,我是铃铛儿如果你是一个王者荣耀老玩家,那么你就一定遇到过这种情况。不管是排位赛或者巅峰赛,你匹配进入到选择英雄阶段的时候就会发现,好多个队友的预选英雄都是同一个位置,这数码宝贝,帝皇龙甲兽FM现身,需要融合进化,实力不一般不得不说,数码宝贝新世纪手游对于帝皇龙甲兽这个IP还是比较重视的。在上周朱庇特兽加强无果之后,又官宣了首个超究极体帝皇龙甲兽FM(俗称战士形态)。虽然与玩家们之前期待的奥米茄兽有点北慕撞车巅峰赛第一,检验出真实水平!赛后北慕劝阻粉丝别带节奏距离S25赛季结束还有不到三天的时间,不少主播都在为巅峰大榜做最后冲刺的准备,尤其是北慕,本身就非常喜欢在赛季末冲榜,如今为了能拿到榜一更是卷得不亦乐乎。近日北慕撞车巅峰赛排名第一外国网友分享自己见过最美的风景,每一张都可以拿来当壁纸疫情开始之后,很多人都没有机会再去看看美丽的大自然了。好在有不少网友会在reddit上的rMostBeautiful讨论组里分享自己见过的最美丽的风景。大到巍峨的山脉,小到可爱的生Steam动作游戏乱揍派对限时特惠开启!支持简中由游戏开发商RebuiltGames制作并发行的动作游戏乱揍派对(PummelParty)现已在Steam平台开启特惠促销活动,游戏原价50元,40折扣后价格为30元,截止日期为1山水谣贵州印象文黄芳没有理由对贵州印象不好。山峰层峦叠嶂秀峰挺立,溶洞千姿百态绚丽奇妙,民族村寨山清水秀竹林葱茏,民族风情多姿多彩引人入胜,瀑布无所不在气势非凡,石头山林灵动古怪,文化遗迹闻名遐贵州独到的卤味秘籍青岩猪脚自古民间就有句老话南方卤,北方酱,位于西南方的贵州也有着独到的卤味秘籍,以青岩古镇命名的青岩猪脚更是贵州卤味中的翘楚。今天就让小编来带你走进这座青岩古镇,赏美景,品美食。青岩古镇位40岁女人尽量不要羽绒服配裙子,学袁泉这样穿,气质好到让人羡慕很多女性对于穿搭都是十分关注的,但是每次都认为自己的搭配有些不尽人意,假如你对自己的搭配能力感到怀疑,那么可以在今年去看看日杂或者明星的穿搭。在这篇文章中,建议40岁女人尽量不要羽邓超孙俪协议离婚因孩子选择不公开,夫妻俩携儿女合体现身破谣言邓超孙俪夫妇一直都是娱乐圈中的明星夫妻,两人结婚已有十年一直非常恩爱。不过,近日网上却频频传出邓超孙俪私下已经离婚的消息,引起不少网友热议。近日,一则邓超孙俪已经离婚,还签好了离婚周迅认真过冬第一人,羽绒服搭配针织裙保暖裤,看似邋遢很元气因为长期生活在镜头里的原因,女明星们好像一年四季都穿着或华美,或仙气飘飘,或性感的服装,展示着自己的好身材,即使在寒风瑟瑟的冬天依旧露腿露腰不含糊。但是离开聚光灯,回归普通生活,明王思聪三亚庆祝生日,几十个网红相伴,未来每年4百亿租等他收王思聪又在海南三亚庆祝自己的生日,这次王思聪的排场依然非常大。当天王思聪直接在酒店的公开场地包了一块地方,现场还有灯光音乐等等,简直就是一个大型的户外派对。当天很多网红也是参加了,买鲈鱼,选购肚子大还是肚子小的,口感差别大,别买错鲈鱼是深受大家喜爱的一种鱼类,无论是淡水鲈鱼还是海鲈鱼,都以肉质细嫩鲜而不腥而著称,范仲淹曾用一句江上往来人,但爱鲈鱼美,道出鲈鱼的鲜嫩肥美。鲈鱼和其他食材一样,也是有着好坏优劣之最穷造芯中企做出块差芯片,为何还被央视赞为科学脊梁?文华商韬略吴苏倪光南柳传志都没有做到的事,居然被一个小作坊做到了!当年,参与国内第一台大型计算机研制的倪光南院士在倪柳之争中败退,离开联想,1999年加入方舟科技。随后,第一款搭载黑莓手机今天彻底死了,但黑莓活得比你想象的滋润得多前两天世超看到一个新闻,说黑莓(BlackBerry)手机死了。有差友可能会说,它不是早就宣布退出手机市场了么。确实嗷但准确来讲,这一次,它才算真正躺进棺材里。因为从今天(1月4日试点版App上架,数字人民币推广全面提速数字货币推广,哪受益?分享新生活试点版App上架,数字人民币推广全面提速无论是从政府公共事业类支付项目以及日常消费商业场景快速增加的角度,还是从数字人民币个人钱包的数量快速增长的角度,数字人民币的推广正数字人民币未来大趋势本微信公众号提供的所有资讯观点技术分析理念等,只供学习闲聊,文章内容不构成您的任何买卖操作建议事件驱动据中国人民银行网站报道,2022年中国人民银行工作会议于12月27日召开。会议低成本创业,第一次做什么比较好?低成本创业,第一次做什么比较好?不是每个人都能创业成功,但总会有敢于冒险的人去创业。如果是第一次创业,其实很多人都没有经验,自然就会问做什么内容比较好。所以,我们就来谈谈第一次创业2022年富有幽默哲理的金句(六)1。云南白药说我只能治疗你的外伤,至于心灵的创伤,你得找我的兄弟,今日头条创作者一一四鉴。2。谁说海水不可斗量?自从大海瞅了你一眼,眼泪都哭干了,只剩下海盐了。3。你又不是倾国倾城