Springboot整合AOP和redis的示例詳解
aop
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>開啟自動代理
注意:在完成了引入AOP依賴包后,一般來說并不需要去做其他配置。使用過Spring注解配置方式的人會問是否需要在程序主類中增加@EnableAspectJAutoProxy來啟用,實際并不需要。
因為在AOP的默認配置屬性中,spring.aop.auto屬性默認是開啟的,也就是說只要引入了AOP依賴后,默認已經增加了@EnableAspectJAutoProxy。
日志切面
@Component
@Aspect
@Slf4j
public class WebLogAspect {
@Pointcut("(execution(public * com.zking.ssm.web..*.*(..))) || (execution(public * com.zking.ssm.controller..*.*(..)))")
public void pointcut(){
?
}
@Before("pointcut()")
public void before(JoinPoint joinPoint){
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if(attributes!=null){
HttpServletRequest request = attributes.getRequest();
log.info("請求地址URL:"+request.getRequestURL().toString());
log.info("請求方式HTTP_METHOD:"+request.getMethod());
log.info("客戶端地址IP:"+request.getRemoteAddr());
log.info("訪問方法CLASS_METHOD:"+joinPoint.getSignature().getDeclaringTypeName());
log.info("訪問方法中的參數ARGS:"+ Arrays.toString(joinPoint.getArgs()));
}
}
}格式:
- execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)throws-pattern?)
- 修飾符匹配(modifier-pattern?)
- 返回值匹配(ret-type-pattern)可以為*表示任何返回值,全路徑的類名等
- 類路徑匹配(declaring-type-pattern?)
- 方法名匹配(name-pattern)可以指定方法名 或者 代表所有, set 代表以set開頭的所有方法
- 參數匹配((param-pattern))可以指定具體的參數類型,多個參數間用“,”隔開,各個參數也可以用“”來表示匹配任意類型的參數,如(String)表示匹配一個String參數的方法;(,String) 表示匹配有兩個參數的方法,第一個參數可以是任意類型,而第二個參數是String類型;可以用(..)表示零個或多個任意參數
- 異常類型匹配(throws-pattern?)
- 其中后面跟著“?”的是可選項
druid數據庫連接池
參考springboot03-mybatis.md
redis springboot整合redis pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--lettuce依賴commons-pool2-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.8.0</version>
</dependency>yaml
spring:
redis:
host: 127.0.0.1
port: 6379
password:
lettuce:
pool:
max-active: 8 #連接池最大連接數(使用負值表示沒有限制)默認為8
max-wait: -1ms #連接池最大阻塞等待時間(使用負值表示沒有限制)默認為-1
max-idle: 8 #連接池中的最大空閑連接 默認為8
min-idle: 5 # 連接池中的最小空閑連接 默認為0自動配置,參考:org.springframework.boot.autoconfigure.data.redis.RedisProperties
RedisConfig
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
// 配置redisTemplate
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
RedisSerializer stringSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringSerializer); // key序列化
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); // value序列化
redisTemplate.setHashKeySerializer(stringSerializer); // Hash key序列化
redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer()); // Hash value序列化
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
?
}RedisService
public interface RedisService {
void setObj(String key, Object obj, long timeout);
void setObj(String key, Object obj);
Object getObj(String key);
}
@Service("redisService")
public class RedisServiceImpl implements RedisService {
@Resource
private RedisTemplate redisTemplate;
@Override
public void setObj(final String key, Object obj, long timeout) {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
operations.set(key, obj, timeout, TimeUnit.SECONDS);
}
?
@Override
public void setObj(String key, Object obj) {
setObj(key,obj,60*60*15);
}
?
@Override
public Object getObj(final String key) {
Object o = redisTemplate.opsForValue().get(key);
return o;
}
?
}使用
@Service
public class CustomerServiceImpl implements CustomerService {
@Autowired
private CustomerMapper customerMapper;
@Autowired
private RedisService redisService;
@Override
public Customer selectByPrimaryKey(Integer id) {
Customer customer = (Customer)redisService.getObj("springboot:ssm:customer:"+id);
if(customer==null){
customer = customerMapper.selectByPrimaryKey(id);
redisService.setObj("springboot:ssm:customer:"+id,customer);
}
return customer;
}
}客戶端工具
在后面 springboot 整合 redis 的時候會用到連接池,所以這里先來介紹下 Redis中的連接池:
客戶端連接 Redis 使用的是 TCP協議,直連的方式每次需要建立 TCP連接,而連接池的方式是可以預先初始化好客戶端連接,所以每次只需要從 連接池借用即可,而借用和歸還操作是在本地進行的,只有少量的并發(fā)同步開銷,遠遠小于新建TCP連接的開銷。另外,直連的方式無法限制 redis客戶端對象的個數,在極端情況下可能會造成連接泄漏,而連接池的形式可以有效的保護和控制資源的使用
下面以Jedis客戶端為例,再來總結下 客戶端直連方式和連接池方式的對比
| 優(yōu)點 | 缺點 | |
|---|---|---|
| 直連 | 簡單方便,適用于少量長期連接的場景 | 1. 存在每次新建/關閉TCP連接開銷 2. 資源無法控制,極端情況下出現連接泄漏 3. Jedis對象線程不安全(Lettuce對象是線程安全的) |
| 連接池 | 1. 無需每次連接生成Jedis對象,降低開銷 2. 使用連接池的形式保護和控制資源的使用 | 相對于直連,使用更加麻煩,尤其在資源的管理上需要很多參數來保證,一旦規(guī)劃不合理也會出現問題 |
Jedis vs Lettuce
Jedis 和 Lettuce 是 Java 操作 Redis 的客戶端。在 Spring Boot 1.x 版本默認使用的是 jedis ,而在 Spring Boot 2.x 版本默認使用的就是Lettuce。關于 Jedis 跟 Lettuce 的區(qū)別如下:
Jedis在實現上是直接連接的redis server,如果在多線程環(huán)境下是非線程安全的,這個時候只有使用連接池,為每個Jedis實例增加物理連接 Lettuce的連接是基于Netty的,連接實例(StatefulRedisConnection)可以在多個線程間并發(fā)訪問,應為StatefulRedisConnection是線程安全的,所以一個連接實例(StatefulRedisConnection)就可以滿足多線程環(huán)境下的并發(fā)訪問,當然這個也是可伸縮的設計,一個連接實例不夠的情況也可以按需增加連接實例。
Lettuce
同4.1
jedis pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
?
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>yml
spring:
redis:
host: 127.0.0.1
port: 6379
password:
jedis:
pool:
max-active: 8 #連接池最大連接數(使用負值表示沒有限制)默認為8
max-wait: -1ms #連接池最大阻塞等待時間(使用負值表示沒有限制)默認為-1
max-idle: 8 #連接池中的最大空閑連接 默認為8
min-idle: 5 # 連接池中的最小空閑連接 默認為0到此這篇關于Springboot整合AOP和redis的文章就介紹到這了,更多相關Springboot整合AOP和redis內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
并發(fā)編程之Java內存模型volatile的內存語義
這篇文章主要介紹了并發(fā)編程之Java內存模型volatile的內存語義,理解volatile特性的一個好辦法是把對volatile變量的單個讀/寫,看成是使用同一個鎖對單個讀/寫操作做了同步。下面我們一起進入文章看看具體例子吧,需要的小伙伴可以參考下2021-11-11
Springboot整合spring-boot-starter-data-elasticsearch的過程
本文詳細介紹了Springboot整合spring-boot-starter-data-elasticsearch的過程,包括版本要求、依賴添加、實體類添加、索引的名稱、分片、副本設置等,同時,還介紹了如何使用ElasticsearchRepository類進行增刪改查操作2024-10-10
IntelliJ?IDEA無公網遠程Linux服務器環(huán)境開發(fā)過程(推薦收藏)
下面介紹如何在IDEA中設置遠程連接服務器開發(fā)環(huán)境并結合Cpolar內網穿透工具實現無公網遠程連接,然后實現遠程Linux環(huán)境進行開發(fā),感興趣的朋友跟隨小編一起看看吧2023-12-12

