【发布时间】:2018-03-20 02:18:45
【问题描述】:
我正在尝试制作像 ibatis @Select 这样的自定义注释。
总之,目标是
- 将一些数据附加到方法具有自定义注释的参数中
先看看终点——ArtistNodeRepository.java
@Repository
public interface ArtistNodeRepository {
@CreateNode(tid = "artist")
public Node create(Map data) throws Exception;
}
CreateNode注解的作用是将data.put("type", "artist")放入参数Map中。
这里是注解 - CreateNode.java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface CreateNode {
String[] values() default "";
String tid();
}
为了控制器注解,我准备了这个BeanPostProcessor - NodeAnnotationProcessor.java
@Component
public class NodeAnnotationProcessor implements BeanPostProcessor {
private ConfigurableListableBeanFactory configurableListableBeanFactory;
@Autowired
public NodeAnnotationProcessor(ConfigurableListableBeanFactory configurableListableBeanFactory) {
super();
this.configurableListableBeanFactory = configurableListableBeanFactory;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
this.scanNodeAnnotation(bean, beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// this.scanNodeAnnotation(bean, beanName);
return bean;
}
protected void scanNodeAnnotation(Object bean, String beanName){
this.configureMethodAction(bean);
}
private void configureMethodAction(Object bean){
Class<?> managedBeanClass = bean.getClass();
ReflectionUtils.MethodCallback methodCallback = new NodeMethodCallback(configurableListableBeanFactory, bean);
ReflectionUtils.doWithMethods(managedBeanClass, methodCallback);
}
}
我不清楚将MethodCallback 放在postProcessBeforeInitialization 或postProcessAfterInitialization 的哪个位置。在我看来,它应该在after,因为我正在尝试操纵方法的参数
最后,这是MethodCallback - NodeMethodCallback.java
public class NodeMethodCallback implements ReflectionUtils.MethodCallback {
private Logger logger = LoggerFactory.getLogger(NodeMethodCallback.class);
private ConfigurableListableBeanFactory beanFactory;
private Object bean;
private static int AUTOWIRE_MODE = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
public NodeMethodCallback(ConfigurableListableBeanFactory beanFactory, Object bean) {
this.beanFactory = beanFactory;
this.bean = bean;
}
@Override
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
logger.info("doWith method info :: " + String.valueOf(bean) + "." + bean.getClass().getName());
/*
What I expected is Printing ArtistNodeRepository Class with create Method
But It prints something like ...
SessionFlashMapManager
DefaultRequestToViewNameTranslator
...
*/
try {
logger.info("When I call you :: " + method.getName()); // I expect method which contains @CreateNode annotation, but it is not ...
Annotation[] methodAnnotations = method.getDeclaredAnnotations();
boolean isTarget = false;
String tid = "";
for(Annotation anno : methodAnnotations) {
logger.info("annotation Class :: " + anno.getClass().getName());
if(isTarget) break;
if(anno instanceof CreateNode) {
logger.info("CreateNode annotation found");
CreateNode createNode = method.getDeclaredAnnotation(CreateNode.class);
tid = createNode.tid();
isTarget = true;
}
}
if(!isTarget) return;
ReflectionUtils.makeAccessible(method);
/*
Do Somthing with Parameter ...
Do Somthing with Parameter ...
Do Somthing with Parameter ...
Do Somthing with Parameter ...
Do Somthing with Parameter ...
*/
} catch (Exception e ){
logger.error("ERROR", e);
}
}
}
问题是...在doWith 中我找不到ArtistNodeRepository 实例。
我应该如何处理MethodCallback 和BeanPostProcessor 来实现目标?
好的示例代码和好的答案一样好。
【问题讨论】:
标签: java spring annotations customization