カスタム アノテーションでアノテーションを付けたい with フィールドとハンドラ メソッドがあります@Controller
。@Autowired
例えば、
@Controller
public class MyController{
@Autowired
public MyDao myDao;
@RequestMapping("/home")
@OnlyIfXYZ
public String onlyForXYZ() {
// do something
return "xyz";
}
}
カスタムアノテーション@OnlyIfXYZ
の例を次に示します。Controller Bean の作成を傍受し、独自の CGLIB プロキシを渡し、Spring が autowired フィールドなどのプロパティを設定できるようにすることを考えていました。
を使用してみましたが、残りのプロセスを短絡させるInstantiationAwareBeanPostProcessor
ため、そのソリューションはうまく機能しません。以下のようpostProcessBeforeInstantiation()
に試してみましたpostProcessAfterInitialization()
public class MyProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// Here the bean autowired fields are already set
return bean;
}
@Override
public Object postProcessAfterInitialization(Object aBean, String aBeanName) throws BeansException {
Class<?> clazz = aBean.getClass();
// only for Controllers, possibly only those with my custom annotation on them
if (!clazz.isAnnotationPresent(Controller.class))
return aBean;
Object proxy = Enhancer.create(clazz, new MyMethodInterceptor());
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
try {
// get the field and copy it over to the proxy
Object objectToCopy = field.get(aBean);
field.set(proxy, objectToCopy);
} catch (IllegalArgumentException | IllegalAccessException e) {
return aBean;
}
}
return proxy;
}
}
このソリューションは、リフレクションを使用して、ターゲット Bean のすべてのフィールドをプロキシ Bean にコピーします (私の好みではハックです)。しかし、インターセプトしているメソッドの引数でない場合、 HttpServletRequest
andオブジェクトにアクセスすることはできません。HttpServletResponse
Spring Bean 作成ロジックに注入して、Spring がそのプロパティを設定する前に独自のプロキシ コントローラーを注入できる別のコールバックはありますか? コントローラー ハンドラー メソッドの定義に含まれているかどうかに関係なく、オブジェクトとオブジェクトにアクセスできる必要があります。引数として。HttpServletRequest
HttpServletResponse
NB@Autowired
フィールドはプロキシでもあり、注釈が付けられている@Transactional
ため、Spring はそれをプロキシします。
編集: AOP ソリューションは、メソッド呼び出しをインターセプトするためにうまく機能しますが、メソッド引数がまだない場合HttpServletRequest
、オブジェクトにアクセスする方法が見つかりません。HttpServletResponse
私はおそらくHandlerInterceptorAdapterを使用することになりますが、OOPを必要としないメソッドにオーバーヘッドを追加しないように、OOPでそれができることを望んでいました.