tor*_*gat 5 java proxy spring annotations
在我的 Spring 应用程序中,我有使用 Spring 缓存机制的组件。每个@Cacheable注释指定要使用的缓存。我想自动发现启动时所需的所有缓存,以便可以自动配置它们。
最简单的方法似乎是创建一个标记接口(例如:)CacheUser供每个缓存组件使用:
@Component
public class ComponentA implements CacheUser {
@Cacheable("dictionaryCache")
public String getDefinition(String word) {
...
}
}
Run Code Online (Sandbox Code Playgroud)
然后我会让 Spring 自动发现这个接口的所有实现,并将它们自动连接到一个配置列表,该列表可以在配置缓存管理器时使用。这有效。
@Autowired
private Optional<List<CacheUser>> cacheUsers;
Run Code Online (Sandbox Code Playgroud)
我的计划是获取每个发现的类并找到所有用@Cacheable. 从那里我将访问注释的属性并获取缓存名称。我正在使用AnnotationUtils.findAnnotation()来获取注释声明。
这就是计划失败的地方。Spring 实际上连接代理而不是原始组件,并且注释不会复制到代理的方法中。我发现的唯一解决方法是利用代理实现Advised提供对代理类的访问这一事实:
((Advised)proxy).getTargetSource().getTargetClass().getMethods()
Run Code Online (Sandbox Code Playgroud)
从那里我可以获得原始注释,但这种方法显然很脆弱。
所以两个问题,真的:
@Cacheable我项目中的所有用途吗?我很乐意没有标记界面。谢谢!
Spring 有很多基础设施接口,可以帮助您进入容器和/或 bean 的生命周期。为了您的目的,您想使用 aBeanPostProcessor和SmartInitializingSingleton.
该BeanPostProcessor会得到一个回调中的所有构造豆,你只需要实现的postProcessAfterInitialization方法。您可以在该方法中检测注释并填充缓存列表。
然后在SmartInitializingSingletonsafterSingletonsInstantiated方法中,您使用此列表来引导/初始化您的缓存。
类似于以下内容(未经测试,但应该给您一个想法)。
public class CacheInitialingProcessor implements BeanPostProcessor, SmartInitializingSingleton {
private final Set<String> caches = new HashSet<String>();
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
Class<?> targetClass = AopUtils.getTargetClass(bean);
ReflectionUtils.doWithMethods(targetClass, new ReflectionUtils.MethodCallback() {
@Override
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
Cacheable cacheable = AnnotationUtils.getAnnotation(method, Cacheable.class);
if (cacheable != null) {
caches.addAll(Arrays.asList(cacheable.cacheNames()));
}
}
});
return bean;
}
@Override
public void afterSingletonsInstantiated() {
for (String cache : caches) {
// inti caches.
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1234 次 |
| 最近记录: |