Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make Spring Service Classes Final?

Tags:

java

spring

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.
}
like image 302
fastcodejava Avatar asked Apr 17 '10 05:04

fastcodejava


People also ask

Can you make the @bean method final in Spring?

Why can't @Bean methods be final either? A class annotated with @Configuration cannot be final because Spring will use CGLIB to create a proxy for @Configuration class. CGLIB creates subclass for each class that is supposed to be proxied, however since the final class cannot have subclass CGLIB will fail.

Is @service mandatory in spring boot?

If there is an @Bean method creating an instance you don't need an @Service or friends. Also both @Controller and @RestController on a single class don't make sense use either not both.

What does @service annotation do in Spring?

Spring @Service annotation is a specialization of @Component annotation. Spring Service annotation can be applied only to classes. It is used to mark the class as a service provider.

What does @service do in spring boot?

It is used to mark the class as a service provider. So overall @Service annotation is used with classes that provide some business functionalities. Spring context will autodetect these classes when annotation-based configuration and classpath scanning is used.


2 Answers

Spring will create a JDK dynamic proxy rather than a CGLIB proxy if the following are true:

  1. aop:config has proxy-target-classes set to false
  2. Any other namespace configurations (e.g. tx:transaction-management) also have proxy-target-classes set to false
  3. 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.

like image 176
Saish Avatar answered Oct 27 '22 18:10

Saish


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.

like image 27
Bozho Avatar answered Oct 27 '22 18:10

Bozho