Java 拦截器和装饰器之间的区别
Java中的拦截器和装饰器之间有什么区别吗?严格地说,我可以用decorator实现拦截器不可能实现的东西吗 除了我必须检查方法名称以在拦截器中添加方法特定行为的问题:Java 拦截器和装饰器之间的区别,java,jakarta-ee,design-patterns,decorator,interceptor,Java,Jakarta Ee,Design Patterns,Decorator,Interceptor,Java中的拦截器和装饰器之间有什么区别吗?严格地说,我可以用decorator实现拦截器不可能实现的东西吗 除了我必须检查方法名称以在拦截器中添加方法特定行为的问题: @Nice @Interceptor public class NiceGreeterInterceptor { @AroundInvoke public Object decorate(InvocationContext ic) throws Exception { Method method = ic.get
@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;
}
}
}
拦截器:
@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
public class GreeterDecorator implements Greeter {
@Inject
@Any
@Delegate
private Greeter greeter;
@Override
public String greet() {
return "NEW " + greeter.greet();
}
}
或者说我可以用拦截器复制装饰器的所有行为,但使用装饰器更舒适,这是合理的吗?Decorator
一个不同点是,正如您的示例所示,对于decorator,您通常会为每个装饰类/接口编写一个decorator
装饰器示例
拦截器
使用拦截器,这是概念的一部分,您可以为一组类/方法编写一个拦截器,例如,您可以拦截所有方法,并确保事务在调用之前打开,在调用之后关闭
拦截器示例
声明一个(要匹配的内容),在这里您可以匹配MyDao类中以insert开头、具有任何参数和任何返回类型的任何方法
@Pointcut("execution(* com.example.dao.MyDao.insert*(..))")
public void insertPointcut() {
}
然后声明一个引用切入点的
@Around(value = "com.example.SystemArchitecture.insertPointcut()")
public void interceptMethod(ProceedingJoinPoint pjp) {
// do pre-work
Object retVal = pjp.proceed();
// do post work
return retVal;
}
}
拦截器更灵活,但假设您更改了方法名称,如果您使用decorator,您可能会遇到编译器错误,使用拦截器,它将不匹配并且不会执行您的“环绕”逻辑。Decorators与拦截器非常相似,但有两个有趣的区别:
Ref:通常,装饰器用于添加新功能或修改现有功能。它使用组合作为继承的替代。装饰器通常提供装饰类中不可用的附加API(方法) 另一方面,AOP(例如拦截器)用于增强现有行为。它不会添加额外的API,通常也不会修改现有的功能。它是通过调用现有功能触发的,并通过采取一些操作进行响应;但是现有的功能以及现有的API保持不变 我不熟悉JEE实现,因此它们可能模糊了这两种模式之间的界限。比较的要点是
能否引入新方法或仅在现有方法周围执行@Interceptor
是否可以覆盖现有方法或仅附加其他行为@Interceptor
可以跨包和类层次结构应用,还是受其中一个层次结构的约束@Decorator
除了这两种模式之间的功能差异之外,考虑潜在的性能差异也可能是有趣的。我预计
@Interceptor
会慢得多,因为它需要在运行时检查方法调用,而@Decorator
调用可以在编译时解析。但是拦截器也可以使用ic.getTarget()获取引用
decorator自动应用于实现相同接口的类(使用自定义限定符除外)。所以不止一个装饰类。同意,它是一对一或一对多,但同样,你有接口,所以它是高度面向对象的。使用AOP,它更灵活,因为您可以使用类型筛选器(例如,代理某个类的所有方法)以及裸字符串reg ex匹配筛选器(例如,代理所有以select开头的方法,并且是com.example.dao包的一部分)。您能否用regex匹配筛选器的示例将您的注释添加到您的答案中,没有完全的reg ex支持,但您有一些通配符匹配。谢谢。所以理论上我可以用拦截器复制装饰器的所有行为?