springboot cache @ EnableCaching instance
- 2021-12-11 07:21:33
- OfStack
springboot Cache @ EnableCaching
Most of the time, the bottleneck of the system lies in 1 more complex IO operation, such as reading the database. If 1 more stable data, 1 general solution is to use cache. spring boot provides a relatively simple caching scheme. Simple caching can be accomplished by using @ EnableCaching.
There are many implementations of cache, such as ConcurentHashMapCache, GuavaCache, EnCacheCache, etc. spring and boot have default implementations. This article does not go deep into the source code interpretation, first of all, use it.
Here we simulate the User to be cached
class User {
private Long id;
private String name;
// setter getter
}
Then our business object:
import javax.annotation.PostConstruct;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.stereotype.Component;
/**
* @author micro
* @date 2017 Year 8 Month 2 Day
* @description :
*/
@Component
@EnableCaching
public class UserDao {
private Map<Long, User> userMap;
@PostConstruct
public void init() {
// Analog database
userMap = new HashMap<Long, User>();
userMap.put(1L, new User(1L,"micro1"));
userMap.put(2L, new User(2L, "micro2"));
}
@Cacheable("user") // Annotation key Property can execute the cache object user( It can be understood as 1 A map) Adj. key
public User getUser(Long userId) {
System.out.println(" Query database :userId ->" + userId);
return userMap.get(userId);
}
@Cacheable(value = "nameCache", key = "#name")
public User getUserByName(Long userId, String name) {
System.out.println(" Query database :userId ->" + userId);
return userMap.get(userId);
}
@Cacheable("nameCache")
public User getUserByName(String name) {
System.out.println(" Query database :userName : " + name);
for (Long k : userMap.keySet()) {
if (userMap.get(k).equals(name)) {
return userMap.get(k);
}
}
return null;
}
@CachePut("user") // And Cacheable The difference is Cacheable Look at the cache first. If there is, directly cache and swap it back. CachePut It is called every time and the return value is put in the cache
public User getUser2(Long userId) {
System.out.println(" Query database :userId : " + userId);
return userMap.get(userId);
}
@CacheEvict("user")
public void removeFromCache(Long userId) {
return ;
}
}
Then we write the startup class:
@SpringBootApplication
public class CacheTest implements CommandLineRunner {
@Autowired
private UserDao userDao;
public static void main(String[] args) {
new SpringApplication(CacheTest.class).run(args);
}
@Override
public void run(String... args) throws Exception {
System.out.println(" No. 1 1 Secondary query ");
System.out.println(userDao.getUser(1L));
System.out.println(" No. 1 2 Secondary query ");
System.out.println(userDao.getUser(1L));
userDao.removeFromCache(1L);// Remove cache
System.out.println(" No. 1 3 Secondary query ");
userDao.getUser(1L);// There is no cache
System.out.println("--------");
// Test different key Cache
userDao.getUserByName("micro1");
userDao.getUserByName(1L, "micro1");// Parameters specified name For key This read cache
}
}
Print results:
First inquiry
Query database: userId- > 1
User@65da01f4
Second inquiry
User@65da01f4
Third inquiry
Query database: userId- > 1
--------
Query database: userName: micro1
Working principle of Spring @ EnableCaching
1. Developers use annotation @ EnableCaching
2. Note @ EnableCaching Import CachingConfigurationSelector
3. CachingConfigurationSelector decides which configuration classes to introduce according to the annotation @ EnableCaching attribute AdviceMode mode
PROXY
: AutoProxyRegistrar, ProxyCachingConfiguration;
ASPECTJ
AspectJCachingConfiguration;
This paper takes mode=PROXY as an example.
4. Importing CachingConfigurationSelector into AutoProxyRegistrar will ensure that there is an automatic proxy creator (APC) in the container;
Used to ensure that a proxy creator is available when the target bean needs to be proxy5. ProxyCachingConfiguration defines the following infrastructure to the container bean
bean with name org. springframework. cache. config. internalCacheAdvisor of Type BeanFactoryCacheOperationSourceAdvisor bean with name cacheOperationSource and type CacheOperationSourceMetadata used to get the Spring Cache annotation that is finally applied when the method is called
bean with name cacheInterceptor and type CacheInterceptor1 MethodInterceptor, AOP Advice wrapped around the target bean for operating Cache.
6. AutoProxyRegistrar processes the creation of each bean in the container startup stage, and if there is a method in the bean that applies Spring Cache annotation, creates a corresponding proxy object for it, and wraps the BeanFactoryCacheOperationSourceAdvisor bean defined above;
7. The bean method with Spring Cache annotation is called. In fact, the call first occurs on the proxy object, first reaches cacheInterceptor, and then is the call of the target bean method;
cacheInterceptor handles both pre-call caching and on-call caching