• 在Spring中使用自定义的Annotation


    需求:我希望在Spring的controller或service中就能方便访问某个cache,采用依赖注入的方式。调用形式为:

    @CacheProvider(cacheName = "xxx", providerName="ehcache")
    ICache userCache;
    
    ICache是一个包含get,put基本cache API的接口。这样我只要告诉我需要什么访问的cache名称,以及类型就能轻松操纵我的cache了。


    于是我写了个Cache的Annotation,由于是第一次写Annotation,顺便学习了一把。主要包括两部分:

    1. Annotation的定义,这个不难,例子到处是。


      @Retention(RetentionPolicy.RUNTIME)
      @Target(value= ElementType.FIELD)
      public @interface CacheProvider{
          CACHE_PROVIDER {EHCACHE, REDIS, MEMCACHED};
      
          String cacheName();
          CACHE_PROVIDER provider() CACHE_PROVIDER.REDIS;
      }
    2. Annotation的解析。要扫描所有代码,对出现自定义Annotation的地方做处理。先写一个解析器,然后注册到Spring中,让Spring在运行时执行解析器。

      解析器可以采用Spring AOP编程模型,或者实现BeanFactoryPostProcessor, BeanPostProcessor接口。因为我的需求是根据Annotation动态注入一个对象,类似于@Autowired。所以我采用的是后者的编程模型。

      

    ()
    CacheProviderProcessor BeanFactoryPostProcessor, BeanPostProcessor, ApplicationContextAware, InitializingBean {
    
        ApplicationContext ;
    postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) BeansException {
            Map<String, Object> map = beanFactory.getBeansWithAnnotation(.);
    
            (String key : map.keySet()) {
                System..println(+ key );
            }
        }
    
        afterPropertiesSet() Exception {
            Map<String, Object> map = .getBeansWithAnnotation(.);
            (String key : map.keySet()) {
                System..println(+ key );
            }
        }
    
        Object postProcessBeforeInitialization(Object bean, String beanName) BeansException {
    bean;
        }
    
        Object postProcessAfterInitialization(Object bean, String beanName) BeansException {
    Field[] fields = bean.getClass().getDeclaredFields();
            (Field field : fields) {
                cacheProvider = field.getAnnotation(.);
                {
                    (cacheProvider != ){
                        (! field.isAccessible()) {
                            field.setAccessible();
                        }
    
                        String cacheName = cacheProvider.cacheName();
                        CacheProvider.CACHE_PROVIDER provider = cacheProvider.provider();
                        (provider == CacheProvider.CACHE_PROVIDER.){
                            CacheManager cacheManager = ((EhCacheCacheManager) .getBean()).getCacheManager();
                            EhcacheCacheProvider ehcacheCacheProvider = EhcacheCacheProvider(cacheManager, cacheName);
                            ehcacheCacheProvider.postCacheManager();
                            field.set(bean, ehcacheCacheProvider);
                        }
                    }
                }(Exception ex){
                    ex.printStackTrace();
                }
    
            }
            bean;
        }
    
        setApplicationContext(ApplicationContext applicationContext) BeansException {
            .= applicationContext;
    
        }
    
    
    }




  • 相关阅读:
    Qt中的标准对话框之QMessageBox
    OpenCV相机标定坐标系详解
    typedef定义数组类型
    导出csv文件(使用a标签)
    获取过去某个时刻时间戳
    查看有没有绑这个host
    $.param()序列化对象
    推荐一个好用的模版引擎工具
    node定时任务
    使用vscode打断点
  • 原文地址:https://www.cnblogs.com/xiuquan/p/5349385.html
Copyright © 2020-2023  润新知