spring 组件 - JiyangM/spring GitHub Wiki
在实例化bean 前后进行操作
- postProcessBeforeInitialization
- postProcessAfterInitialization
应用:
spring-data-redis
在使用spring cache 时,利用 spring的一些注解@Cacheable、@CachePut可以创建以及更新缓存的操作,为了解决缓存失效时间无法在方法上指定,定义了一个注解。
然后实现 BeanPostProcessor 接口。在postBefore 方法中进行操作,判断当前bean instance RedisCacheManager,如果是,则通过反射获取所有包下面的被注解修饰的方法。 从中获取失效时间 以及key 对应的失效时间。然后通过CacheManager.setExpires。设置到缓存中。
Reflections reflections = new Reflections("com.longdai", new MethodAnnotationsScanner());
Set<Method> methods = reflections.getMethodsAnnotatedWith(CacheExpire.class);
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CacheExpire {
/*
过期时间,以秒为单位
*/
@AliasFor("value")
long expireAfter() default 0;
@AliasFor("expireAfter")
long value() default 0;
}
直接上代码,比如我的application.properties文件有如下配置(这里说明一下SpringBoot应用默认的配置文件名就叫做application.properties,可以直接放在当前项目的根目录下,或者一个名叫config的子目录下)
@Configuration
public class MyProjectc implements EnvironmentAware {
@Override
public void setEnvironment(Environment environment) {
String projectName = environment.getProperty("project.name");
System.out.println(projectName);
}
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new SwaggerInterceptor()).addPathPatterns("/v2/api-docs/**");
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (!(handler instanceof HandlerMethod)) {
return true;
}
HandlerMethod handlerMethod = (HandlerMethod) handler;
AssertAuth assertAuth = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), AssertAuth.class);
if (assertAuth == null) {
return true;
}
boolean autoLogin = authHandler.autoLogin(request);
if (!autoLogin) {
throw new InvalidAuthException();
}
return true;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof RedisCacheManager) {
Reflections reflections = new Reflections("com.longdai", new MethodAnnotationsScanner());
Set<Method> methods = reflections.getMethodsAnnotatedWith(CacheExpire.class);
log.debug("Methods annotated with CacheExpire count is:{}", methods.size());
for (Method method : methods) {
Annotation[] annotations = method.getAnnotations();
String[] cacheNames = {};
long expireAfter = 0;
Optional<Annotation> cacheableAnnotation = Arrays.stream(annotations).filter(annotation -> annotation instanceof Cacheable).findFirst();
Optional<Annotation> cacheExpireAnnotation = Arrays.stream(annotations).filter(annotation -> annotation instanceof CacheExpire).findFirst();
Optional<Annotation> cachePutAnnotation = Arrays.stream(annotations).filter(annotation -> annotation instanceof CachePut).findFirst();
if (!cacheExpireAnnotation.isPresent()) {
return bean;
}
CacheExpire cacheExpire = (CacheExpire) cacheExpireAnnotation.get();
expireAfter = cacheExpire.value();
if (cacheableAnnotation.isPresent()) {
Cacheable cacheable = (Cacheable) cacheableAnnotation.get();
cacheNames = cacheable.value().length > 0 ? cacheable.value() : cacheable.cacheNames();
}
if (cachePutAnnotation.isPresent()) {
CachePut cachePut = (CachePut) cachePutAnnotation.get();
cacheNames = cachePut.value().length > 0 ? cachePut.value() : cachePut.cacheNames();
}
if (cacheNames.length > 0 && expireAfter > 0) {
log.info("cacheNames:{}", GsonUtils.toJson(cacheNames));
log.info("expireAfter:{}", expireAfter);
long finalExpireAfter = expireAfter;
Stream.of(cacheNames).forEach(cacheName -> expireMap.put(cacheName, finalExpireAfter));
}
}
if (!expireMap.isEmpty()) {
((RedisCacheManager) bean).setExpires(expireMap);
log.info("redis expire map has been set!");
}
}
return bean;
}
配置自动刷新
https://www.cnblogs.com/chry/p/7260778.html
springboot 的自动配置注解 在我们想要自己实现 datasource 的时候可以进行排除掉。