Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between interceptors and decorators

Are there any differences between interceptors and decorators in Java? Strictly speaking, can I implementing things with decorators which are not possible with interceptors and vice versa?

Except the problem that I would have to examine the method name to add method-specific behavior in an interceptor:

Interceptor:

@Nice
@Interceptor
public class NiceGreeterInterceptor {
  @AroundInvoke
  public Object decorate(InvocationContext ic) throws Exception {
    Method method = ic.getMethod();
    String methodName = method.getName();
    Object result = ic.proceed();
    if (methodName.equals("greet")) {
      return "NEW " + result;
    }
  }
}

Decorator:

@Decorator
public class GreeterDecorator implements Greeter {
  @Inject
  @Any
  @Delegate
  private Greeter greeter;

  @Override
  public String greet() {
    return "NEW " + greeter.greet();
  }
}

Or is it legitimate to say that I can reproduce all the behavior of decorators with interceptors but it is more comfortable to use decorators?

like image 313
ammerzon Avatar asked Feb 29 '16 18:02

ammerzon


People also ask

What are interceptors for business methods?

An interceptor is a method that is automatically called when the business methods of an Enterprise JavaBeans (EJB) are invoked or lifecycle events of an EJB occur. There are three kinds of interceptor methods: business method interceptors, timeout method interceptors (which are new in EJB3.

What is a decorator method?

Decorator Method is a Structural Design Pattern which allows you to dynamically attach new behaviors to objects without changing their implementation by placing these objects inside the wrapper objects that contains the behaviors.

What is an interceptor software?

In the field of software development, an interceptor pattern is a software design pattern that is used when software systems or frameworks want to offer a way to change, or augment, their usual processing cycle.

What does a decorator do in Java?

Decorator patterns allow a user to add new functionality to an existing object without altering its structure. So, there is no change to the original class. The decorator design pattern is a structural pattern, which provides a wrapper to the existing class.


2 Answers

Decorator

One difference would be, as your example shows it, with decorator you usually write 1 decorator per 1 decorated class/interface.

Decorator example

interface Worker {
    void work();
}

class Decorated implements Worker {

    public void work() {

    }
}

class DecoratorByInheritance extends Decorated {

    public void work() {
        // pre
        super.work();
        // post
    }
}

class DecoratorByComposition implements Worker {

    Worker decorated;

    DecoratorByComposition(Worker decorated) {
        this.decorated = decorated;
    }

    public void work() {
        // pre
        this.decorated.work();
        // post
    }
}

Interceptor

With interceptors, which are part of the AOP concept, you write 1 interceptor for a bunch of classes / methods, e.g. you intercept all DAO methods and make sure a transaction is open before the invocation and closed after it.

Interceptor example

Declare a pointcut (what to match), here you match any method from the MyDao class that starts with insert, has any arguments and any return type.

@Pointcut("execution(* com.example.dao.MyDao.insert*(..))")
public void insertPointcut() {
}

Then you declare an around advice which references the pointcut

@Around(value = "com.example.SystemArchitecture.insertPointcut()")
public void interceptMethod(ProceedingJoinPoint pjp) {
        // do pre-work
        Object retVal = pjp.proceed();
        // do post work
        return retVal;
    }
}

Interceptors are more flexible but imagine you change the method name, if you use a decorator, you'll probably get a compiler error, with interceptors, it will just not match and not execute your 'around' logic.

like image 66
Bax Avatar answered Nov 03 '22 08:11

Bax


In general, a decorator is used to add new functionality or modify existing functionality. It uses composition as an alternative to inheritance. Decorators often provide additional APIs (methods) that are not available in the decorated classes.

On the other hand, AOP (e.g. an interceptor) is used to enhance existing behavior. It does not add additional APIs and generally does not modify existing functionality. It is triggered by invocation of existing functionality and responds by taking some action; but the existing functionality as well as the existing API remain unchanged.

I am not familiar with the JEE implementations, so they may have blurred the lines between these two patterns. Important points to compare would be,

  • Can @Interceptor introduce new methods or only execute around existing methods?
  • Can @Interceptor override existing methods or only append additional behavior?
  • Can @Decorator be applied across packages & class hierarchies, or is it constrained by one of these?

In addition to functional differences between the two patterns, it may also be interesting to consider potential performance differences. I would expect @Interceptor to be considerably slower, since it needs to examine method calls at runtime, whereas @Decorator invocations can be resolved at compile time.

like image 21
jaco0646 Avatar answered Nov 03 '22 09:11

jaco0646