봄 캐시 (소스 코드를 파싱) 평신도의 언어와 통합을 사용하여

봄 캐시 (소스 코드를 파싱) 평신도의 언어와 통합을 사용하여

개인 개발 환경

자바 환경 : Jdk1.8.0_60

컴파일러 : 인 IntelliJ의 IDEA 2019.1

springCache 공식 문서 : https://docs.spring.io/spring/docs/5.1.9.RELEASE/spring-framework-reference/integration.html#cache

A, 봄 캐시 추상화

사실, 생성 된 배경 SpringCache 배경으로 봄이 다소 유사한 생산. 코드, 객체 생성 및 복잡한 종속성 자바 EE 프레임 워크 비 대한, 비효율적, 낮은 관찰하기 때문에, 스프링 프레임 워크는 기본적으로, 모든 프로젝트는 (더 봄의 포장을 간소화) 자바 배경 봄 또는 SpringBoot에서 분리 될 수 없다 나왔다 . 일반적으로 스프링 프레임 워크에, 당신은 캐시 지원을 완료하는 데 더 편리하고 간단한 방법이 필요하므로 이제 프로젝트에 직면 높은 동시성 문제가 더 캐싱 애플리케이션의 많은 종류도 증가했다.
SpringCache 자체도 완료 특정 캐시 구현을 충족해야 SpringCache를 사용하는 캐싱 시스템의 추상 실현없이 특정 캐시 용량이다.

  • 캐시 인터페이스 사양은 어셈블리 캐시, 각종 동작의 세트를 상기 캐시로 정의된다;
  • 캐시 인터페이스는 다양한 봄 xxxCache의 구현을 제공 RedisCache, EhCacheCache는 등 ConcurrentMapCache 경우;

둘째, 중요한 메모, 매개 변수

이름 설명
은닉처 캐시 인터페이스 정의 캐시 작업. 이 실현 : RedisCache, EhCacheCache, ConcurrentMapCache 등
CacheManager 캐시 관리자는 캐시 (캐시) 구성 요소를 관리
@Cacheable 구성하는 주된 방법은 요청 파라미터 법에 의해 캐싱 될 수있다
@CacheEvict 캐시 비우기
@CachePut 메소드가 호출되어 있는지 확인하고, 그 결과가 캐시 바랍니다. 차이점은 @Cacheable 각 메소드를 호출할지 여부를 일반적으로 업데이트에서 사용
@EnableCaching 열기 주석 기반 캐싱
의 KeyGenerator 키 생성 전략을 때 캐시 데이터
직렬화 캐시 데이터 값 때 직렬화 전략
@CacheConfig 노트의이 클래스의 통합 캐시 구성 속성

@ 캐시 가능 / @ CachePut / @ 주요 매개 변수 CacheEvict

이름 설명
스프링 구성 파일에 정의 된 캐시 이름은 적어도 하나의 예를 지정해야 @Cacheable (값 = "mycache") 또는 @Cacheable를 (값 = { "cache1", "cache2에"}
@Cacheable (값 = "testcache"키 = "# 아이디") : 당신이 SpEL을 지정하지 않을 경우 기본 매개 변수는 모든 방법에 따라, 예를 들어 결합되어, 식에 따라 작성 지정하려면 캐시 키는 비어있을 수 있습니다
조건 버퍼 조건, 비어있을 수 있으며,이 SpEL을 작성, 그것은 단지 캐시 / 캐시 지우기 예 참, 참 또는 거짓 반환 @Cacheable (값 = "testcache"상태 = "#의 userName.length을 ()> 2")
하지 않는 한 네거티브 캐싱. 조건의 결과가 TRUE 인 경우,이 캐시되지 않습니다. @Cacheable (값 = "testcache"않는 = "#의 userName.length ()> 2")
allEntries (@CacheEvict) 모든 캐시 내용을 취소할지 여부를 true로 지정하면, 기본값은 false이며, 메소드 호출 즉시 지우기 예를 들어 캐시 : @CachEvict (값 = "testcache", allEntries = TRUE)
beforeInvocation (@CacheEvict) 이 실행 방법 전에 비워 여부 방법은 빈 캐시에서 수행되지 않은 경우 당신은 기본적으로 사실이다 지정한 실행 방법은 예외가 발생하면, 그것은 예를 들어 캐시를 삭제하지 않을 경우, 디폴트는 false입니다 @ CachEvict (값 = "testcache", beforeInvocation = TRUE)

세, SpEL을 컨텍스트 데이터

봄 캐시 SpEL을 우리가 테이블 봄 공식 문서에서 직접 그려, 사용하는 데이터에 대한 몇 가지 컨텍스트를 제공합니다 :

이름 위치 기술
methodName로 루트 개체 현재의 방법은 이름이라고합니다 #의 root.methodname
방법 루트 개체 현재 메소드가 호출됩니다 #의 root.method.name
목표 루트 개체 현재 대상 객체 인스턴스라고 # root.target
targetClass를 루트 개체 현재 클래스는 대상 객체라고 #의 root.targetClass
인수 루트 개체 매개 변수 목록은 현재의 방법이라고 #의 root.args [0]
캐시 루트 개체 현재 메서드 호출은 캐시 목록을 사용하여 root.caches # [0] .name을
인수의 이름 실행 컨텍스트 상기 방법의 파라미터는 findArtisan (장인 장인)와 같은 전류를 호출하고, 파라미터들은 artsian.id 번호에 의해 얻을 수있다 #의 artsian.id
결과 실행 컨텍스트 방법의 실행 후 리턴 값 (판정을 행하는 방법 만 유효 cacheEvict 않는 한 beforeInvocation = 거짓)를 #결과

넷째, 실제

1. 수입 의존도

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

2. 시작 클래스 캐시 코멘트를 열고 @EnableCaching

/**
 * 1、开启基于注解的缓存 @EnableCaching
 * 2、标注缓存注解即可
 *    @Cacheable
 *    @CacheEvict
 *    @CachePut
 */
@SpringBootApplication
@EnableCaching  //开启缓存
public class CacheApplication{
    public static void main(String[] args) {
        SpringApplication.run(CacheApplication.class, args);
    }

}

3. 캐시 @Cacheable

실행중인 프로세스 :

@Cacheable먼저 자동으로 생성 된 캐시 캐시 구성 요소를 확보 할 경우이 방법을 실행하기 전에, cacheNames / 값 지정된 이름에 따라 획득 한 쿼리 캐시 (캐시 구성 요소)로 이동합니다.

소스 분석 :

public @interface Cacheable {
    // cacheNames/value:指定缓存组件的名字;将方法的返回结果放在哪个缓存中,是数组的方式,可以指定多个缓存
    @AliasFor("cacheNames")
    String[] value() default {};
    @AliasFor("value")
    String[] cacheNames() default {};

    // 缓存数据使用的key;可以用它来指定。默认是使用方法参数的值
    String key() default "";

    // key的生成器;可以自己指定key的生成器的组件id,key/keyGenerator:二选一使用;
    String keyGenerator() default "";

    // 指定缓存管理器;或者cacheResolver指定获取解析器 作用得到缓存集合
    String cacheManager() default "";
    String cacheResolver() default "";

    // 条件符合则缓存,编写SpEL:condition = "#a0>1":第一个参数的值大于1的时候才进行缓存
    String condition() default "";
    
    // 条件符合则不缓存,编写SpEL:unless = "#a0==2":如果第一个参数的值是2,结果不缓存;
    String unless() default "";

    // 是否使用异步模式,是否启用异步模式
    boolean sync() default false;
}

드릴 비트 :

@Cacheable(value = "emp" ,key = "targetClass + methodName +#p0")
public Employee getEmp(Integer id){
    System.out.println("查询"+id+"号员工");
    Employee emp = employeeMapper.getEmpById(id);
    return emp;
}

단차 구덩이 :

1, 속성이 value/cacheNames필요하며 네임 스페이스의 조각에 저장된 캐시를 지정합니다.

2、属性key是使用的spEL表达式

注意:踩坑,如果你把methodName换成method运行会报错,观察它们的返回类型,原因在于methodNameStringmethohMethod

Employee实体类一定要实现序列化public class Employee implements Serializable,否则会报java.io.NotSerializableException异常。

4.更新 @CachePut

@CachePut既调用方法,又更新缓存数据;同步更新缓存。简单来说就是用户修改数据同步更新缓存数据。

源码分析:(皮一下,去事故与@Cacheable相同,不做过多解释了,狗头护体~~~)

public @interface CachePut {
    
    @AliasFor("cacheNames")
    String[] value() default {};
    
    @AliasFor("value")
    String[] cacheNames() default {};

    String key() default "";

    String keyGenerator() default "";

    String cacheManager() default "";

    String cacheResolver() default "";

    String condition() default "";

    String unless() default "";
}

操练一下

注意该注解的value/cahceNameskey 必须与要更新的缓存相同,也就是与@Cacheable 相同。

@CachePut(value = "emp" ,key = "#employee.id")
public Employee updateEmp(Employee employee){
    System.out.println("updateEmp:"+employee);
    employeeMapper.updateEmp(employee);
    return employee;
}

5.清除 @CacheEvict

@CachEvict 的作用 主要针对方法配置,能够根据一定的条件对缓存进行清空 。

源码分析

public @interface CacheEvict {
    // 同上同上同上
    @AliasFor("cacheNames")
    String[] value() default {};
    @AliasFor("value")
    String[] cacheNames() default {};
    String key() default "";
    String keyGenerator() default "";
    String cacheManager() default "";
    String cacheResolver() default "";
    String condition() default "";

    // 指定清除这个缓存中所有的数据,示例:@CachEvict(value=”emp”,allEntries=true)
    boolean allEntries() default false;

    /*
     * 示例: @CachEvict(value=”emp”,beforeInvocation=true)
     * 代表清除缓存操作是在方法运行之前执行,无论方法是否出现异常,缓存都清除
     *
     * 示例: @CachEvict(value=”emp”,beforeInvocation=false)(默认)
     * 缓存的清除是否在方法之前执行 , 默认代表缓存清除操作是在方法执行之后执行;如果出现异常缓存就不会清除
     */
    boolean beforeInvocation() default false;
}

操练一下

//方法调用后清空所有缓存
@CacheEvict(value="accountCache", allEntries=true)
public void deleteEmp() {
    employeeMapper.deleteAll();
}

6.组合 @Caching

有时候我们可能组合多个Cache注解使用,此时就需要@Caching组合多个注解标签了。

源码分析

public @interface Caching {
    // 用于指定多个缓存设置操作
    Cacheable[] cacheable() default {};
    
    // 用于指定多个缓存更新操作
    CachePut[] put() default {};
    
    // 用于指定多个缓存失效操作
    CacheEvict[] evict() default {};
}

操练一下

// @Caching 定义复杂的缓存规则
@Caching(
    cacheable = {
        @Cacheable(value="emp",key = "#lastName")
    },
    put = {
        @CachePut(value="emp",key = "#result.id"),
        @CachePut(value="emp",key = "#result.email")
    }
)
public Employee getEmpByLastName(String lastName){
    return employeeMapper.getEmpByLastName(lastName);
}

7.全局配置 @CacheConfig

当我们需要缓存的地方越来越多,可以使用@CacheConfig(cacheNames = {"emp"})注解来统一指定value的值,这时可省略value,如果你在你的方法依旧写上了value,那么依然以方法的value值为准。

源码分析

public @interface Caching {
    // 用于指定多个缓存设置操作
    Cacheable[] cacheable() default {};
    
    // 用于指定多个缓存更新操作
    CachePut[] put() default {};
    
    // 用于指定多个缓存失效操作
    CacheEvict[] evict() default {};
}

操练一下

@CacheConfig(cacheNames = {"emp"}, /*keyGenerator = "cacheKeyGenerator"*/)
public class EmployeeServiceImpl implements EmployeeService {
    @Override
    @Cacheable(/*value = ‘emp’*/ key = "targetClass + methodName +#p0")
    public Employee getEmp(Integer id){
        Employee emp = employeeMapper.getEmpById(id);
        return emp;
    }
}

8.主键生成策略 keyGenerator

操练一下

创建CacheConfig配置类

@Configuration
public class CacheConfig {

    /**
     * 生成缓存主键策略 (方法名+参数)
     * 
     * @return KeyGenerator
     */
    @Bean("cacheKeyGenerator")
    public KeyGenerator keyGenerator() {
        return (target, method, params) -> (method.getName() + " [ " + Arrays.asList(params) + " ]");
    }
}

可以在@CacheConfig指定生成策略,也可以在@Cacheable/@CachePut/@CacheEvict指定key生成策略

@CacheConfig(cacheNames = {"emp"}, keyGenerator = "cacheKeyGenerator")
public class EmployeeServiceImpl implements EmployeeService {
    @Override
    @Cacheable(/*value = ‘emp’,keyGenerator = "cacheKeyGenerator"*/)
    public Employee getEmp(Integer id){
        Employee emp = employeeMapper.getEmpById(id);
        return emp;
    }
}

추천

출처www.cnblogs.com/yoci/p/11595226.html