amm*_*zon 12 java design-patterns decorator java-ee interceptor
Java中的拦截器和装饰器之间是否存在任何差异?严格来说,我可以使用装饰器实现一些拦截器无法实现的东西,反之亦然吗?
除了我必须检查方法名称以在拦截器中添加特定于方法的行为的问题:
拦截器:
@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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
装饰:
@Decorator
public class GreeterDecorator implements Greeter {
@Inject
@Any
@Delegate
private Greeter greeter;
@Override
public String greet() {
return "NEW " + greeter.greet();
}
}
Run Code Online (Sandbox Code Playgroud)
或者说我可以用拦截器重现装饰器的所有行为是合法的,但是使用装饰器会更舒服吗?
一个区别是,正如您的示例所示,使用装饰器,您通常每1个装饰类/接口编写1个装饰器.
使用拦截器(它是AOP概念的一部分),您可以为一堆类/方法编写1个拦截器,例如,您可以拦截所有DAO方法,并确保事务在调用之前打开并在之后关闭.
在Spring AOP中的一个拦截器的例子,首先你声明一个切入点(匹配什么),在这里你匹配MyDao类中以insert开头的任何方法,有任何参数和任何返回类型.
@Pointcut("execution(* com.example.dao.MyDao.insert*(..))")
public void insertPointcut() {
}
Run Code Online (Sandbox Code Playgroud)
然后你声明一个引用切入点的around建议
@Around(value = "com.example.SystemArchitecture.insertPointcut()")
public void interceptMethod(ProceedingJoinPoint pjp) {
// do pre-work
Object retVal = pjp.proceed();
// do post work
return retVal;
}
}
Run Code Online (Sandbox Code Playgroud)
不过,每个部分都有自己的优点/缺点.例如拦截器更灵活,但想象你改变方法名称,如果你使用装饰器,你可能会得到一个编译器错误,有拦截器,它只是不匹配而不执行你的'around'逻辑.
通常,装饰器用于添加新功能或修改现有功能。它使用组合作为继承的替代方法。装饰器通常提供装饰类中不可用的其他API(方法)。
另一方面,AOP(例如拦截器)用于增强现有行为。它不会添加其他API,并且通常不会修改现有功能。它是由调用现有功能触发的,并通过采取一些措施做出响应;但是现有功能以及现有API均保持不变。
我不熟悉JEE的实现,因此它们可能使这两种模式之间的界限变得模糊。要比较的重点是
@Interceptor引入新方法还是仅在现有方法周围执行?@Interceptor覆盖现有方法还是仅附加其他行为?@Decorator应用于包和类层次结构,还是受其中之一约束?除了两种模式之间的功能差异之外,考虑潜在的性能差异也可能很有趣。我希望@Interceptor它会慢得多,因为它需要在运行时检查方法调用,而@Decorator调用可以在编译时解决。