Alexey Berezkin
Alexey Berezkin

Reputation: 1543

Applying aspects depending on advised object invocation place

Please consider the following: we have a Spring bean B which is advised with a number of aspects: A1, A2. We have some other Spring beans: X, Y, Z — and B is injected to all of them. The question is: how can we make aspects of B to be applied or not depending on bean from which B is invoked (X, Y, Z)? In my particular task I need to make one aspect (for example, A2) to be bypassed when B is invoked from particular bean (for example, Z), while in other invocations all aspects must be applied.

Upvotes: 1

Views: 94

Answers (1)

Alexey Berezkin
Alexey Berezkin

Reputation: 1543

The decision was quite simple. Z contains the reference to B, and this reference is of type Advised. This interface allows accessing different properties of advised object, including its aspects. This allows creating new advised object which includes only needed aspects of B. The code snippet follows.

All types and identifiers are given in respect to example from the original question. B is ab interface, b is a reference. Code snippet is from Z bean.

Class<?>[] classes = {B.class};
AdvisedSupport config = new AdvisedSupport(classes);
try {
    config.setTargetSource(((Advised) b).getTargetSource());
} catch (Exception e) {
    e.printStackTrace();
}
for (Advisor advisor : ((Advised) b).getAdvisors()) {
    Advice advice = advisor.getAdvice();
    if ((advice instanceof AbstractAspectJAdvice) && "advice.A2".equals(
            ((AbstractAspectJAdvice) advice).getAspectName())) {
        // Do not add A2 advisor
    } else {
        config.addAdvisor(advisor);
    }
}
DefaultAopProxyFactory factory = new DefaultAopProxyFactory();
B newB = (B)factory.createAopProxy(config).getProxy();

Now newB reference is ready for use.

Upvotes: 1

Related Questions