spring 组件 - JiyangM/spring GitHub Wiki

BeanPostProcessor

在实例化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;
}

EnvironmentAware 可以读取配置文件中的配置数据

直接上代码,比如我的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);
    }
 }  

WebMvcConfigurerAdapter 可以添加拦截器

 @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new SwaggerInterceptor()).addPathPatterns("/v2/api-docs/**");
    }

HandlerInterceptorAdapter 可以定义拦截器


关于自定义注解的操作:

  • 在拦截器中判断访问权限
@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;
    }
  • 在bean初始化时 做操作

 @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;
    }

@RefreshScope 注释

配置自动刷新

https://www.cnblogs.com/chry/p/7260778.html

@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})

springboot 的自动配置注解 在我们想要自己实现 datasource 的时候可以进行排除掉。

⚠️ **GitHub.com Fallback** ⚠️