让春季服务课程成为最终课程?

2022-09-05 00:09:03

我可以使春季服务课程成为最终课程吗?这样做有什么坏处吗?没有人会扩展这个类。有什么问题吗?

public final class MyService {
   // Depedencies go here.
}

答案 1

不要制作它们。如果你在具体类上使用任何AOP(包括事务支持),spring将使用CGLIB来动态扩展你的类,以便制作代理。CGLIB工作的要求是让你的类非。否则将引发异常。finalfinal


答案 2

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

  1. aop:config 已将代理目标类设置为 false
  2. 任何其他命名空间配置(例如 tx:transaction-management)也将代理目标类设置为 false
  3. 您的类实现接口

如果这三者都为真,则可以将类声明为 final。(如果您愿意,您甚至可以将类包私有化,并将构造函数私有化,Spring将能够实例化它)。

否则,Spring将创建一个CGLIM代理。如果 Bean 中没有公共方法,您仍然可以声明类 final(假设它没有用 @Repository 修饰,并且您没有声明 PersistenceExceptionPostBeanProcessor)。一旦有了一个公共方法,就不能使用 CBLIB 代理声明该类最终状态。(注意:通过 CGLIB 代理时,您必须至少有一个包私有、无参数构造函数)。

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

最后(没有双关语的意思),尽可能使课程最终确定。具体继承既经常混淆被滥用(参见脆弱的基础问题)。最终类还允许一些编译器优化。


推荐