让Spring Service Classes最终完成?

fas*_*ava 6 java spring

我可以让春季服务班最终完成吗?这样做有什么害处吗?没有人会延长课程.有什么问题吗?

public final class MyService {
   // Depedencies go here.
}
Run Code Online (Sandbox Code Playgroud)

Boz*_*zho 19

不要制作它们final.如果在具体类上使用任何AOP(包括事务支持),spring将使用CGLIB动态扩展您的类以生成代理.CGLIB工作的要求是让你的课程不是final.否则将抛出异常.

  • 好吧,然后_can_,但也要小心.您可能会在某些时候为它们添加一些AOP. (2认同)
  • 这些工具的缺陷是无法使用"最终"类,这是正确的OO设计的必要条件(例如,参见"实用API设计"一书 - 甚至是GoF书).有**方法来测试最终课程; 像CGLIB这样的工具已经过时了. (2认同)

Sai*_*ish 7

如果满足以下条件,Spring将创建JDK动态代理而不是CGLIB代理:

  1. aop:config将proxy-target-classes设置为false
  2. 任何其他命名空间配置(例如tx:transaction-management)也将proxy-target-classes设置为false
  3. 您的类实现了一个接口

如果这三个都是真的,那么你可以声明最终的类.(如果你愿意,你甚至可以使类包私有和构造函数私有,Spring将能够实例化它).

否则,Spring将创建一个CGLIB代理.如果bean中没有公共方法,您仍然可以声明类final(假设它没有使用@Repository修饰并且您没有声明PersistenceExceptionPostBeanProcessor).一旦有了单个公共方法,就无法使用CBLIB代理声明类final.(注意:通过CGLIB代理时,必须至少有一个package-private,no-argument构造函数).

以上什么时候有用?假设您有一个服务接口(所有服务通常应该具有接口),并且具有包私有的实现bean.该服务使用JDK动态代理.因此,它可能是最终的,在包外不可见,泄漏的实现细节较少.假设服务需要数据访问对象.如果没有其他服务使用此DAO,为什么要将其或其任何方法公开?如果DAO上的所有方法都是包私有的,那么服务实现仍然可以连接DAO并使用其方法.从包外部,调用者只能看到界面(一件好事)以及界面签名中使用的任何类型.

最后(没有双关语意),尽可能做一个班级决赛.具体的继承往往会混淆被滥用(见脆弱的基础问题).最终类还允许一些编译器优化.