在Spring中使用自定义的Annotation
需求:我希望在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;
}
}
浙公网安备 33010602011771号