Bassem 06/06
In questo post vediamo la differenza tra le annotazioni @Repository
, @Service
, @Configuration
e @Controller
e come crearne una personalizzata, in modo che le nostre classi siano inizializzate nel contenitore Spring IoC (Inversion of Control) come qualsiasi classe annotata con tali annotazioni.
Creando annotazioni personalizzate per le dipendenze, possiamo isolare il nostro livello di logica (cuore dell'applicazione) dal framework utilizzato. Se volessimo migrare la nostra applicazione su un altro framework, dovremmo solo modificare quelle annotazioni senza toccare i vari servizi.
Prima di tutto, le annotazioni sopra menzionate e la @Component
sono annotazioni comuni di "Bean" e utilizzate come tipologia per qualsiasi componente gestito da Spring. Le classi annotate verranno rilevate automaticamente tramite la scansione iniziale fatta da Spring.
In realtà, non c'è una grande differenza tra @Repository
, @Service
, @Configuration
e @Controller
, tutti sono annotati con @Component
. Si può vedere il codice dell'annotazione @Service
nel seguente snippet:
package org.springframework.stereotype;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
@AliasFor(annotation = Component.class)
String value() default "";
}
Sono usati per differenziare gli strati:
@Service
, per le classi di logica di business;
@Controller
, per il livello di rappresentazione;
@Configuration
, per qualsiasi configurazione;
@Repository
, per le classi di accesso alle base dati. Un'eccezione qui, Spring fornisce automaticamente un PersistenceExceptionTranslationPostProcessor (che è necessario), rendendo la classe idonea per le eccezioni Spring DataAccessException.
Creiamo un'annotazione di servizio personalizzata chiamata @OurCustomService
, che viene utilizzata per annotare le nostre classi di servizio e renderle idonee per il contenitore IoC di Spring.
Prima di tutto, nel nostro pom.xml abbiamo bisogno della seguente dipendenza:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
Ora creiamo la nostra annotazione personalizzata:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Component;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface OurCustomService {
@AliasFor(annotation = Component.class)
String value() default "";
}
È una copia dell'annotazione Spring @Service
. Da notare che l'interfaccia stessa è annotata con @Component
.
Quindi creiamo il nostro livello di servizio creando un'interfaccia e la sua implementazione. Quest'ultimo è annotato con @OurCustomService
:
public interface DemoService {
void print();
}
@OurCustomService
public class DemoServiceImpl implements DemoService {
private static final Logger log = LoggerFactory.getLogger(DemoServiceImpl.class);
@Override
public void print() {
log.info("""
This Message is from:
DemoService
""");
}
}
Infine, testiamo il nostro codice nella classe main, cercando il ApplicationContext
per il nostro bean DemoServiceImpl
:
@SpringBootApplication
public class CustomAnnotaionsApplication {
public static void main(String[] args) {
SpringApplication.run(CustomAnnotaionsApplication.class, args);
}
@Component
class StartUp implements CommandLineRunner {
@Autowired
private ApplicationContext applicationContext;
@Autowired
private DemoService demo;
private static final Logger log = LoggerFactory.getLogger(StartUp.class);
@Override
public void run(String... args) throws Exception {
demo.print();
log.info("""
Found the custom service witn name: {}
""", List.of(applicationContext.getBeanNamesForType(DemoService.class)).stream().collect(Collectors.joining(" , ")));
}
}
}
Quando eseguiamo la nostra applicazione, possiamo trovare l'invocazione nei log:
2022-06-04 18:25:40.930 INFO 51696 --- [ main] d.s.c.service.DemoServiceImpl : This Message is from:
DemoService
2022-06-04 18:25:40.931 INFO 51696 --- [ main] .s.c.CustomAnnotaionsApplication$StartUp : Found the custom service witn name: demoServiceImpl
Tutto qua, spero che lo troviate utile. Il codice della completa applicazione può essere trovato su GitHub.
In questo post vediamo la differenza tra le annotazioni Repository, Service, Configuration e Controller e come crearne una personalizzata con #springboot e #Java#italiano https://t.co/MW4XfvaNqy
— soloCoding (@s0l0c0ding) June 10, 2022