У меня есть класс обслуживания, реализованный в Java 6/Spring 3, который требует аннотации для ограничения доступа по ролям.Точка привязки Spring AOP, которая соответствует аннотации по интерфейсу
Я определил аннотацию под названием RequiredPermission, который имеет в качестве атрибута его значение одного или нескольких значений из перечислений под названием OperationType:
public @interface RequiredPermission {
/**
* One or more {@link OperationType}s that map to the permissions required
* to execute this method.
*
* @return
*/
OperationType[] value();}
public enum OperationType {
TYPE1,
TYPE2;
}
package com.mycompany.myservice;
public interface MyService{
@RequiredPermission(OperationType.TYPE1)
void myMethod(MyParameterObject obj);
}
package com.mycompany.myserviceimpl;
public class MyServiceImpl implements MyService{
public myMethod(MyParameterObject obj){
// do stuff here
}
}
У меня также есть следующее определение аспект:
/**
* Security advice around methods that are annotated with
* {@link RequiredPermission}.
*
* @param pjp
* @param param
* @param requiredPermission
* @return
* @throws Throwable
*/
@Around(value = "execution(public *"
+ " com.mycompany.myserviceimpl.*(..))"
+ " && args(param)" + // parameter object
" && @annotation(requiredPermission)" // permission annotation
, argNames = "param,requiredPermission")
public Object processRequest(final ProceedingJoinPoint pjp,
final MyParameterObject param,
final RequiredPermission requiredPermission) throws Throwable {
if(userService.userHasRoles(param.getUsername(),requiredPermission.values()){
return pjp.proceed();
}else{
throw new SorryButYouAreNotAllowedToDoThatException(
param.getUsername(),requiredPermission.value());
}
}
объект параметра содержит имя пользователя, и я хочу найти требуемую роль для пользователя, прежде чем разрешить доступ к этому методу.
Когда я помещаю аннотацию на метод в MyServiceImpl, все работает отлично, привязка pointcut и нос. Но я считаю, что аннотация является частью контракта на обслуживание и должна быть опубликована с помощью интерфейса в отдельный пакет API. И, очевидно, я бы не хотел ставить аннотацию на определение и реализацию сервиса (DRY).
Я знаю, что есть случаи в Spring AOP, где аспекты инициируются аннотациями одним способом интерфейса (например, Transactional). Здесь есть специальный синтаксис или это просто невозможно из коробки.
PS: Я не разместил свою конфигурацию пружины, поскольку она работает нормально. И нет, это не мои первоначальные классы и имена методов.
PPS: На самом деле, вот соответствующая часть моей весенней конфигурации:
<aop:aspectj-autoproxy proxy-target-class="false" />
<bean class="com.mycompany.aspect.MyAspect">
<property name="userService" ref="userService" />
</bean>
Итак, если я правильно понимаю, самое лучшее решение, которое вы нашли для вашего первоначального вопроса (то есть, имеющие пометку в интерфейс, а не в реализации) заключается в том, чтобы сопоставить весь пакет интерфейсов поставщика услуг, а затем зайти в ProceedingJoinPoint, чтобы узнать аннотации метода в интерфейсе? Возможно ли это? Это отличный поток, и вы не хотите начинать новый с тем же вопросом! Благодаря!! – espinchi
@espinchi на самом деле я был настолько расстроен, что я скопировал все аннотации из интерфейса к классу внедрения и принудительно применил это с помощью жесткого модульного теста, который проверял все методы как на интерфейсе, так и на классе реализации для идентичных аннотаций. Я не знаю точно, АОП. Я бы сказал, что это не работает надежно, ведь –