需求:我希望在Spring的controller或service中就能方便访问某个cache,采用依赖注入的方式。调用形式为:
@CacheProvider(cacheName = "xxx", providerName="ehcache") ICache userCache; ICache是一个包含get,put基本cache API的接口。这样我只要告诉我需要什么访问的cache名称,以及类型就能轻松操纵我的cache了。
于是我写了个Cache的Annotation,由于是第一次写Annotation,顺便学习了一把。主要包括两部分:
Annotation的定义,这个不难,例子到处是。
@Retention(RetentionPolicy.RUNTIME) @Target(value= ElementType.FIELD) public @interface CacheProvider{ CACHE_PROVIDER {EHCACHE, REDIS, MEMCACHED}; String cacheName(); CACHE_PROVIDER provider() CACHE_PROVIDER.REDIS; }
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; } }