首页 文章 精选 留言 我的

精选列表

搜索[基础搭建],共10000篇文章
优秀的个人博客,低调大师

SpringBoot2.0 基础案例(11):配置AOP切面编程,解决日志记录业务

一、AOP切面编程 1、什么是AOP编程 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP(面向对象编程)的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。 2、AOP编程特点 1)AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码 2)经典应用:事务管理、性能监视、安全检查、缓存 、日志等 3)aop底层将采用代理机制进行实现 4)接口 + 实现类 :spring采用 jdk 的动态代理Proxy 5)实现类:spring 采用 cglib字节码增强 3、AOP中术语和图解 1)target:目标类 需要被代理的类。例如:UserService 2)Joinpoint:连接点 所谓连接点是指那些可能被拦截到的方法。例如:所有的方法 3)PointCut:切入点 已经被增强的连接点。例如:addUser() 4)advice:通知/增强 增强代码。例如:after、before 5)Weaving:织入 指把增强advice应用到目标对象target来创建新的代理对象proxy的过程. 6)proxy 代理类 7) Aspect(切面): 是切入点pointcut和通知advice的结合 一个线是一个特殊的面。 一个切入点和一个通知,组成成一个特殊的面。 二、与SpringBoot2.0整合 1、核心依赖 <!-- AOP依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> 2、编写日志记录注解 package com.boot.aop.config; import java.lang.annotation.*; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface LogFilter { String value() default "" ; } 3、编写日志记录的切面代码 这里分为两种情况处理,一种正常的请求日志,和系统异常的错误日志。核心注解两个。@Aspect和@Component。 package com.boot.aop.config; import com.alibaba.fastjson.JSONObject; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.lang.reflect.Method; @Aspect @Component public class LogAspect { private static final Logger LOGGER = LoggerFactory.getLogger(LogAspect.class) ; @Pointcut("@annotation(com.boot.aop.config.LogFilter)") public void logPointCut (){ } @Around("logPointCut()") public Object around (ProceedingJoinPoint point) throws Throwable { Object result = null ; try{ // 执行方法 result = point.proceed(); // 保存请求日志 saveRequestLog(point); } catch (Exception e){ // 保存异常日志 saveExceptionLog(point,e.getMessage()); } return result; } private void saveExceptionLog (ProceedingJoinPoint point,String exeMsg){ LOGGER.info("捕获异常:"+exeMsg); HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); LOGGER.info("请求路径:"+request.getRequestURL()); MethodSignature signature = (MethodSignature) point.getSignature(); Method method = signature.getMethod(); LOGGER.info("请求方法:"+method.getName()); // 获取方法上LogFilter注解 LogFilter logFilter = method.getAnnotation(LogFilter.class); String value = logFilter.value() ; LOGGER.info("模块描述:"+value); Object[] args = point.getArgs(); LOGGER.info("请求参数:"+ JSONObject.toJSONString(args)); } private void saveRequestLog (ProceedingJoinPoint point){ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); LOGGER.info("请求路径:"+request.getRequestURL()); MethodSignature signature = (MethodSignature) point.getSignature(); Method method = signature.getMethod(); LOGGER.info("请求方法:"+method.getName()); // 获取方法上LogFilter注解 LogFilter logFilter = method.getAnnotation(LogFilter.class); String value = logFilter.value() ; LOGGER.info("模块描述:"+value); Object[] args = point.getArgs(); LOGGER.info("请求参数:"+ JSONObject.toJSONString(args)); } } 4、请求日志测试 @LogFilter("保存请求日志") @RequestMapping("/saveRequestLog") public String saveRequestLog (@RequestParam("name") String name){ return "success:"+name ; } 切面类信息打印 /** * 请求路径:http://localhost:8011/saveRequestLog * 请求方法:saveRequestLog * 模块描述:保存请求日志 * 请求参数:["cicada"] */ 5、异常日志测试 @LogFilter("保存异常日志") @RequestMapping("/saveExceptionLog") public String saveExceptionLog (@RequestParam("name") String name){ int error = 100 / 0 ; System.out.println(error); return "success:"+name ; } 切面类信息打印 /** * 捕获异常:/ by zero * 请求路径:http://localhost:8011/saveExceptionLog * 请求方法:saveExceptionLog * 模块描述:保存异常日志 * 请求参数:["cicada"] */ 三、源代码地址 GitHub地址:知了一笑 https://github.com/cicadasmile 码云地址:知了一笑 https://gitee.com/cicadasmile

优秀的个人博客,低调大师

SpringBoot2.0 基础案例(08):集成Redis数据库,实现缓存管理

一、Redis简介 Spring Boot中除了对常用的关系型数据库提供了优秀的自动化支持之外,对于很多NoSQL数据库一样提供了自动化配置的支持,包括:Redis, MongoDB, Elasticsearch。这些案例整理好后,陆续都会上传Git。SpringBoot2 版本,支持的组件越来越丰富,对Redis的支持不仅仅是扩展了API,更是替换掉底层Jedis的依赖,换成Lettuce。本案例需要本地安装一台Redis数据库。 二、Spring2.0集成Redis 1、核心依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> 2、配置文件 # 端口 server: port: 8008 spring: application: # 应用名称 name: node08-boot-redis # redis 配置 redis: host: 127.0.0.1 #超时连接 timeout: 1000ms jedis: pool: #最大连接数据库连接数,设 0 为没有限制 max-active: 8 #最大等待连接中的数量,设 0 为没有限制 max-idle: 8 #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。 max-wait: -1ms #最小等待连接中的数量,设 0 为没有限制 min-idle: 0 这样Redis的环境就配置成功了,已经可以直接使用封装好的API了。 3、简单测试案例 import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.concurrent.TimeUnit; @RestController public class RedisController { @Resource private StringRedisTemplate stringRedisTemplate ; @RequestMapping("/setGet") public String setGet (){ stringRedisTemplate.opsForValue().set("cicada","smile"); return stringRedisTemplate.opsForValue().get("cicada") ; } @Resource private RedisTemplate redisTemplate ; /** * 设置 Key 的有效期 10 秒 */ @RequestMapping("/setKeyTime") public String setKeyTime (){ redisTemplate.opsForValue().set("timeKey","timeValue",10, TimeUnit.SECONDS); return "success" ; } @RequestMapping("/getTimeKey") public String getTimeKey (){ // 这里 Key 过期后,返回的是字符串 'null' return String.valueOf(redisTemplate.opsForValue().get("timeKey")) ; } } 4、自定义序列化配置 import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import java.io.Serializable; /** * Redis 配置 */ @Configuration public class RedisConfig { private static final Logger LOGGER = LoggerFactory.getLogger(RedisConfig.class) ; /** * 序列化配置 */ @Bean public RedisTemplate<String, Serializable> redisTemplate (LettuceConnectionFactory redisConnectionFactory) { LOGGER.info("RedisConfig == >> redisTemplate "); RedisTemplate<String, Serializable> template = new RedisTemplate<>(); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); template.setConnectionFactory(redisConnectionFactory); return template; } } 5、序列化测试 import com.boot.redis.entity.User; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.ArrayList; import java.util.List; @RestController public class SerializeController { @Resource private RedisTemplate redisTemplate ; @RequestMapping("/setUser") public String setUser (){ User user = new User() ; user.setName("cicada"); user.setAge(22); List<String> list = new ArrayList<>() ; list.add("小学"); list.add("初中"); list.add("高中"); list.add("大学"); user.setEducation(list); redisTemplate.opsForValue().set("userInfo",user); return "success" ; } @RequestMapping("/getUser") public User getUser (){ return (User)redisTemplate.opsForValue().get("userInfo") ; } } 三、源代码地址 GitHub地址:知了一笑 https://github.com/cicadasmile 码云地址:知了一笑 https://gitee.com/cicadasmile

优秀的个人博客,低调大师

SpringBoot2.0 基础案例(06):引入JdbcTemplate,和多数据源配置

一、JdbcTemplate对象 1、JdbcTemplate简介 在Spring Boot2.0框架下配置数据源和通过JdbcTemplate访问数据库的案例。SpringBoot对数据库的操作在jdbc上面做了深层次的封装,使用spring的注入功能,可以把DataSource注册到JdbcTemplate之中。 2、JdbcTemplate核心方法 1)execute方法:可以用于执行任何SQL语句; 2)update方法batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句; 3)query方法及queryFor方法:用于执行查询相关语句; 4)call方法:用于执行存储过程、函数相关语句。 二、SpringBoot2中用法 1、导入Jar包 <!-- 数据库依赖 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.21</version> </dependency> <!-- JDBC 依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> 2、配置数据源信息 spring: application: # 应用名称 name: node06-boot-jdbc datasource: # 数据源一:data_one 库 primary: # 2.0开始的版本必须这样配置 jdbc-url: jdbc:mysql://localhost:3306/data_one #url: jdbc:mysql://localhost:3306/data_one username: root password: 123 driver-class-name: com.mysql.jdbc.Driver # 数据源二:data_two 库 secondary: # 2.0开始的版本必须这样配置 jdbc-url: jdbc:mysql://localhost:3306/data_two #url: jdbc:mysql://localhost:3306/data_two username: root password: 123 driver-class-name: com.mysql.jdbc.Driver 3、数据源代码配置 1)数据源一的配置@Primary 注解表示该数据源作为默认的主数据库。 /** * 数据源一配置 */ @Configuration public class DataOneConfig { @Primary // 主数据库 @Bean(name = "primaryDataSource") @Qualifier("primaryDataSource") @ConfigurationProperties(prefix = "spring.datasource.primary") public DataSource primaryDataSource (){ return DataSourceBuilder.create().build() ; } @Bean(name = "primaryJdbcTemplate") public JdbcTemplate primaryJdbcTemplate ( @Qualifier("primaryDataSource") DataSource dataSource){ return new JdbcTemplate(dataSource); } } 2)数据源二配置 /** * 数据源二配置 */ @Configuration public class DataTwoConfig { @Bean(name = "secondaryDataSource") @Qualifier("secondaryDataSource") @ConfigurationProperties(prefix="spring.datasource.secondary") public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "secondaryJdbcTemplate") public JdbcTemplate secondaryJdbcTemplate( @Qualifier("secondaryDataSource") DataSource dataSource) { return new JdbcTemplate(dataSource); } } 4、编写一个简单的测试类 @RestController public class JdbcController { private static final Logger LOG = LoggerFactory.getLogger(JdbcController.class); // 数据源一 @Autowired @Qualifier("primaryJdbcTemplate") private JdbcTemplate primaryJdbcTemplate ; // 数据源二 @Autowired @Qualifier("secondaryJdbcTemplate") private JdbcTemplate secondaryJdbcTemplate ; /** * 多数据源查询 */ @RequestMapping("/queryData") public String queryData (){ String sql = "SELECT COUNT(1) FROM d_phone" ; Integer countOne = primaryJdbcTemplate.queryForObject(sql,Integer.class) ; Integer countTwo = secondaryJdbcTemplate.queryForObject(sql,Integer.class) ; LOG.info("countOne=="+countOne+";;countTwo=="+countTwo); return "SUCCESS" ; } } 三、源代码地址 GitHub地址:知了一笑 https://github.com/cicadasmile 码云地址:知了一笑 https://gitee.com/cicadasmile

优秀的个人博客,低调大师

语音识别(ASR)基础介绍第三篇——经典做法及术语概念

上一章介绍了万金油特征MFCC,相当于数据的输入已经确定了。 本章尽可能的介绍经典asr做法。其中涉及到的各种概念和思考,了解了之后,和相关专业的人交流,大概就不再迷茫了:D 传统方法也可以按 声学模型 和 语言学模型 的方式来划分。 声学模型主要的职责是,把一段音频处理成类似拼音的形式, 然后交给语言模型来猜: 能够发这些音的单词,怎么组合起来更常见一些。然后找到最可能的组合,便是asr的结果了。 本章介绍的,其实是下图左侧的部分。 一、术语定义 介绍一个概念前,首先要把它依赖的术语说明白,其实asr领域的术语定义并不复杂,反而非常符合直观感觉。换句话说,定义基本是一眼就明白意思并且觉得没有毛病的样子。 上图右侧是传统模型的大致处理流程。里面用到的术语基本都在左侧介绍了。架构解释了整体的处理逻辑: 已知一句话中的一系列单词W ,在MFCC发

优秀的个人博客,低调大师

语音识别(ASR)基础介绍第四篇——当今流行做法与CTC

本篇开始,就进入到了asr当前的流行做法。 这里单独提到了CTC算法。 这个算法对当前asr使用deep learning的方法有重大影响。 总体感觉,写到本篇,工作量反而变得很小。因为进入deep learning时代后,神经网络模型基本都是那么几种,已经不再需要挨个详细介绍。而且看图就能理解的很明白。 所以本篇后半部分基本就是贴图了。。:D 一、CTC 在CTC之前,训练语料要配合上一篇中提到的方法,需要人工把音频中每个时间段对应的是哪个音素的信息标注清楚。 这个工作量和对人及金钱的需求是巨大的。基本都是百万级别手笔。 有个CTC之后, 给定一个音频,就只要告诉这个音频说的是什么文本就好了。 省掉了对齐的那一步。 由此,其重要性可自行判断。 关于CTC,感觉与其这里坑坑洼洼的介绍,不如直接参考这篇知乎的文章——https://z

优秀的个人博客,低调大师

基础如何用 15 行 Python 代码搞定网易云热门歌单?

健身、吃饭、敲代码;等车、撸猫、下午茶……若能佐以合适的音乐当“配餐”,总是惬意非常。本文就将带你爬一爬网易云的那些热门歌单! 心情好或心情坏,点一首歌抚慰你受伤或躁动的心灵——下面教你用 15 行代码搞定热门歌单! 本文使用的是 Selenium 模块,它是一个自动化测试工具,利用它我们可以驱动浏览器执行特定的动作,如点击、下拉等操作,对于一些 JavaScript 渲染的页面来说,此种抓取方式非常有效。 采用了 Chrome 浏览器配合 Selenium 工作,本文的 Python 版本是 3.7.2。 准备工作 1. 若你的环境中没有 Selenium 模块,直接使用 pip 安装即可: pip install selenium 2. 打开谷歌浏览器,检查Chrome的版本:在浏览器地址中输入 chrome://settings/help 回车即可看到: 3. 打开 ChromeDriver 的官方网站(https://sites.google.com/a/chromium.org/chromedriver/downloads),寻找与你当前浏览器版本相对应的 ChromeDriver 下载: 4. 选择你自己的操作系统类型进行下载即可: 5. 以 Windows 为例,下载结束后,将 ChromeDriver 放置在 Python 安装目录下的 Scripts 文件夹即可: 准备工作完成,代码写起来吧~ 小编给大家推荐一个学习氛围超好的地方,python交流企鹅裙:【611+530+101】适合在校大学生,小白,想转行,想通过这个找工作的加入。裙里有大量学习资料,有大神解答交流问题,每晚都有免费的直播课程 迷你爬虫的实现 我们这次的目标是爬取热门歌单,比如网易云音乐中播放量大于 1000万 的歌单信息(歌单名称、链接)。 1. 先来打开网易云的歌单第一页: https://music.163.com/#/discover/playlist/ 2. 使用 Chrome 的开发者工具 <F12> 进行分析: 我们想要拿的信息全在这里: msk,封面 [mask]:有歌单的名称及链接 nb,播放数 [number broadcast]:135万 3. 我们还需要遍历所有的页,使用工具继续分析,找到“下一页”的 URL: 4. 切换至最后一页,拿到最后一页的 URL: 5. 等我们爬取完所有符合的歌单信息后,将其保存在本地; 6.全部工作结束,最后再通过下面的伪代码回顾下整体思路: 7. 爬取的效果如下:

优秀的个人博客,低调大师

Python零基础学习笔记(十)—— 运算符和表达式

知识点: 运算符和表达式 运算符:表示运算的符号 表达式:由变量、常量和运算符组成的式子 算术运算符和算数运算表达式 算术运算符 + - * / % ** // 加 减 乘 除 取模 求幂 取整 算是运算表达式 1 + 1 2*3 a/3 功能:进行相关符号的数学运算,不会改变变量的值 值:相关数据的运算结果 赋值运算符和赋值运算表达式 赋值运算符 = 赋值运算表达式 格式: 变量 = 表达式 功能:计算了等号右侧‘表达式’的值,并赋值给等号左侧的变量 值:赋值结束后变量的值 复合运算符 += a+=b -> a=a+b -= a-=b -> a=a-b *= a*=b -> a=a*b /= a/=b -> a=a/b %= a%=b -> a=a%b **= a**=b -> a=a**b //= a//=b -> a=a//b 练习代码: #算数运算符计算 num1 = 7 num2 = 3 print(num1 + num2) print(num1 - num2) print(num1 * num2) print(num1 / num2) print(num1 % num2) print(num1 ** num2) print(num1 // num2) print("--------") num3 = 2 num4 = num3 +1 print(num4)运算结果: 10 4 21 2.3333333333333335 1 343 2 -------- 3

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册