Make Spring Service Classes Final?
Can I make the spring service classes final? Is there any harm doing that? Nobody is going 开发者_开发问答to extend the class. Is there any issue?
public final class MyService {
// Depedencies go here.
}
Don't make them final
. If you use any AOP (including transaction support) on concrete classes, spring will use CGLIB to dynamically extend your class in order to make a proxy. And the requirement for CGLIB to work is to have your classes non-final
. Otherwise an exception will be thrown.
Spring will create a JDK dynamic proxy rather than a CGLIB proxy if the following are true:
- aop:config has proxy-target-classes set to false
- Any other namespace configurations (e.g. tx:transaction-management) also have proxy-target-classes set to false
- Your class implements an interface
If all three are true, then you can declare the class final. (You can even make the class package-private and the constructor private if you like, Spring will be able to instantiate it).
Otherwise, Spring will create a CGLIB proxy. You can still declare the class final (assuming it is not decorated with @Repository and you do not have a PersistenceExceptionPostBeanProcessor declared) if there are no public methods in the bean. Once you have a single public method, you cannot declare the class final with CBLIB proxying. (Note: you must have at least a package-private, no-argument constructor when proxying via CGLIB).
When is the above useful? Say you have a service interface (all services should generally have interfaces) with an implementation bean that is package private. The service is using JDK dynamic proxying. So, it can be final and non-visible outside the package, leaking fewer implementation details. Say the service needs a data access object. If no other service uses this DAO, why make it or any of its methods public? If all the methods on the DAO are package-private, the service implementation can still wire the DAO in and use its methods. From outside the package, callers only see the interface (a good thing) and any types that are used in the interface signature.
Finally (no pun intended), make a class final whenever you can. Concrete inheritance is both often confusing an abused (see fragile base problem). Final classes also allow some compiler optimizations.
精彩评论