AccessDecisionManagerアクセスの決定を特別なインターフェイスに委譲する独自の実装を行うことで、これを実現しましたAccessDecisionStrategy。
public interface AccessDecisionStrategy {
    void decide(Authentication authentication, MethodInvocation methodInvocation, ConfigAttribute configAttribute);
}
各アクセス決定戦略は、アクセス決定を行うさまざまな方法を表しています。
独自の戦略を簡単に実装できます (他の言語でも - たとえば Scala など)。
public class SomeStrategy implements AccessDecisionStrategy { ...
ご覧のとおり、myAccessDecisionManagerには戦略のマップがあります。manager が使用する戦略は、注釈引数に基づいています。
public class MethodSecurityAccessDecisionManager implements AccessDecisionManager {
    private Map<String, AccessDecisionStrategy> strategyMap;
    public MethodSecurityAccessDecisionManager(Map<String, AccessDecisionStrategy> strategyMap) {
        this.strategyMap = strategyMap;
    }
    @Override
    public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
        ConfigAttribute configAttribute = getSingleConfigAttribute(configAttributes);
        AccessDecisionStrategy accessDecisionStrategy = strategyMap.get(configAttribute.getAttribute());
        if (accessDecisionStrategy == null) {
            throw new IllegalStateException("AccessDecisionStrategy with name "
                    + configAttribute.getAttribute() + " was not found!");
        }
        try {
            accessDecisionStrategy.decide(authentication, (MethodInvocation) object, configAttribute);
        } catch (ClassCastException e) {
            throw new IllegalStateException();
        }
    }
    private ConfigAttribute getSingleConfigAttribute(Collection<ConfigAttribute> configAttributes) {
        if (configAttributes == null || configAttributes.size() != 1) {
            throw new IllegalStateException("Invalid config attribute configuration");
        }
        return configAttributes.iterator().next();
    }
    @Override
    public boolean supports(ConfigAttribute attribute) {
        return true;
    }
    @Override
    public boolean supports(Class<?> clazz) {
        return clazz.equals(MethodInvocation.class);
    }
}
メソッドを保護したい場合@Securedは、戦略の名前である引数を使用して注釈を付けます。
@Secured("GetByOwner")
FlightSpotting getFlightSpotting(Long id);
必要な数の戦略を実装および構成できます。
<bean id="methodSecurityAccessDecisionManager"
      class="some.package.MethodSecurityAccessDecisionManager">
    <constructor-arg>
        <map>
            <entry key="GetByOwner">
                <bean class="some.package.GetByOwnerStrategy"/>
            </entry>
            <entry key="SomeOther">
                <bean class="some.package.SomeOtherStrategy"/>
            </entry>
        </map>
    </constructor-arg>
</bean>
そのアクセス決定マネージャーを挿入するには、次のように入力します。
<sec:global-method-security secured-annotations="enabled"
                            access-decision-manager-ref="methodSecurityAccessDecisionManager">
</sec:global-method-security>
MethodInvocation引数を処理するヘルパー クラスも実装しました。
import org.aopalliance.intercept.MethodInvocation;
public class MethodInvocationExtractor<ArgumentType> {
    private MethodInvocation methodInvocation;
    public MethodInvocationExtractor(MethodInvocation methodInvocation) {
        this.methodInvocation = methodInvocation;
    }
    public ArgumentType getArg(int num) {
        try {
            Object[] arguments = methodInvocation.getArguments();
            return (ArgumentType) arguments[num];
        } catch (ClassCastException | ArrayIndexOutOfBoundsException e) {
            throw new IllegalStateException();
        }
    }
}
これで、戦略のコードで興味深い引数を簡単に抽出して決定を下すことができます。
0タイプの引数番号を取得したいとしましょうLong:
MethodInvocationExtractor<Long> extractor = new MethodInvocationExtractor<>(methodInvocation);
Long id = extractor.getArg(0);