# Spring i Spring Boot. Injecció de dependències
## Què és Spring?
**Spring és un framework per al desenvolupament d'aplicacions i contenidor d'inversió de control (IoC) de codi obert per a la plataforma Java**.
Mecanismes que incorpora Spring:
* Injecció de dependències (DI) per inversió de control (IoC).
* Gestió senzilla de components (POJO’s/Beans).
* Programació orientada a aspectes (AOP):
* Habilita la implementació de rutines transversals.
* Separa les diferents tasques que ha de fer una classe qualsevol dins una aplicació.
* Addició de comportaments a les classes mitjançant l’ús de proxies, és a dir classes que implementen mètodes d’altres classes. Un proxy permet implementar multitud de patrons de disseny d’una aplicació de forma més senzilla.

Font: [campusmvp: spring framework i spring boot](https://www.campusmvp.es/recursos/post/que-son-spring-framework-y-spring-boot-tu-primer-programa-java-con-este-framework.aspx)
Com ja hem comentat al primer punt, un dels punts forts d'Spring és la injecció de dependències, no obstant adicionalment incorpora una sèrie de mòduls "out of the box" com són:
* Spring JDBC
* Spring MVC
* Spring Security
* Spring AOP
* Spring ORM
* Spring Test
Entre altres. Cadascun d'aquests mòduls permeten enfocar el desenvolupament amb Spring cap àmbits específics com l'accés a dades, desenvolupaments basats en model vista controlador, programació orientada a aspectes (afegir funcionalitat adicional sense modificar el codi existent), etc.
## Spring i Spring Boot
Spring Boot és una extensió d'Spring encaminada a eliminar configuracions i plantilles repetitives (anomenat també *boilerplate* configurations/code) i així simplificar el codi d'un desenvolupament i el temps necessari per dur-lo a terme. El que fa SpringBoot és limitar o simplificar el nombre de dependències que podem utilitzar (redueix la flexibilitat envers Spring "pare") i incorporar un servidor encastat (embedded) com és Apache Tomcat, a més d'altres accions.
Pel propòsit del nostre aprenentatge en endavant farem ús d'Spring Boot
## Spring initializr
Spring initializr és un asistent que ens permet crear esquelets de projectes amb Spring Boot, generant artefactes on ja el projecte ens ve estructurat i s'incorporen les dependències necessàries (ja siguin maven o gradle). Un cop disposem d'aquests artefactes podem començar a incorporar components i desenvolupar la nostra aplicació.
Accedirem a https://start.spring.io/index.html on trobarem un menú per poder construir el nostre esquelet de projecte "a la carta":

Penseu que les versions que poden aparèixer a la imatge varien des del moment en el qual s'han escrit aquestes línies. No obstant, en termes generals:
* Secció **Project**: podem triar el gestor de dependències. Tal i com hem fet al llarg del curs continuarem amb Maven.
* Secció **Language**: per triar el llenguatge en el qual desenvoluparem l'aplicació, a triar entre java, Kotlin o Groovy. Tal i com hem fet al llarg del curs continuarem amb Java.
* **Versió d'Spring Boot**: de forma predeterminada ens apareixerà marcada la versió estable. Altres versions que deixa triar són les snapshots i les milestone, les quals estan encara "en construcció".
* Secció **Project Metadata**: on indicarem les "coordenades" del nostre projecte, és a dir, el grup, l'artefacte (nom que tindrà el component construït), etc.
* Secció **Packaging**: Un cop depurat el nostre projecte podem procedir a construir-lo i empaquetar-lo com JAR (java archive, aplicació java) o com WAR (web application, per desplegar en un servidor).
* **Versió de java**: on la versió mínima (i actualment recomanada) és la 17.
* Secció **Dependencies**: Mitjançant el botó "ADD DEPENDENCIES" obtenim un llistat de les dependències que podem utilitzar. Fent clic sobre la dependència llistada la incorporem al nostre projecte.
Per últim disposem dels botons **GENERATE** i **EXPLORE**. Sovint pot resultar interessant fer l'opció EXPLORE abans que GENERATE, ja que ens permet visualitzar com quedarà el pom del nostre projecte i com serà la seva estructura (scaffolding):

El botó GENERATE ens descarregarà un .zip el qual haurem de descomprimir per poder començar a utilitzar-lo amb l'IDE amb el qual treballem de forma habitual.
## Primers passos: projecte d'exemple sense dependències
Sense triar cap dependència (de moment no les necessitem) generarem un primer projecte. Podeu emplenar lliurament els paràmetres de group, artifact, ... si bé veurem que és recomanable no fer ús de guions (alts o baixos) quan informem aquests camps.
Un cop obriu el projecte començarem per explicar alguns detalls i com funciona la injecció de dependències amb spring.
### Què són els beans?
Per diferenciar-los dels EJB (enterprise java bean), Spring defineix un bean com una classe java corrent (POJO) que incorpora una sèrie de metadades de configuració i és gestionada pel contenidor d'inversió de control d'spring (Spring IoC container). Internament l'Spring IoC container conté les interfícies 'BeanFactory' i 'ApplicationContext', les quals proporcionen funcionalitats bàsiques per gestionar els beans (de fet ApplicationContext és una subinterfície de BeanFactory).
La idea és que cada bean tingui clarament delimitat el seu àmbit i la seva funció, segons si és per interaccionar directament amb la base de dades o per poder gestionar els resultats d'una query que fem contra una base de dades i mapejar-los cap una interfície.
### Formes de configurar un bean
Hi podem trobar:
* Configuració legacy amb XML (no ho veurem).
* Configuració amb fitxers de configuració java (Java Config).
* Configuració amb anotacions.
#### Configuració amb anotacions
Com ja vàrem veure amb hibernate, les anotacions són metadades que apliquem sobre el codi i que permetran configurar i controlar el comportament d'Spring boot. Com veurem les anotacions ens permetran definir components, la injecció de dependències, configuracions, etc. entre altres tipus de funcionalitats de forma declarativa.
Una de les anotacions principals ja que habilita la configuració automàtica i l'escaneig de components és `@SpringBootApplication` la qual trobareu a la classe que ens ve per defecte quan creem el projecte:
```
@SpringBootApplication
public class ProjecteexempleApplication {
public static void main(String[] args) {
SpringApplication.run(ProjecteexempleApplication.class, args);
}
}
```
##### Exemple senzill amb anotacions
El que farem tot seguit és crear una carpeta que anomenarem config_anotacions on mostrarem els diferents exemples que treballarem amb anotacions. La crearem al mateix nivell que la classe que conté el main de l'aplicació. En el cas de l'exemple que estem treballant la ficarem penjant de projecteexemple:

Ara com heu vist a la imatge crearem una primera classe anomenada Botiga, la qual sols tindrà el constructor buit:
```
package com.iticbcn.iticbcn.projecteexemple.configanotacions;
import org.springframework.stereotype.Component;
@Component
public class Botiga {
public Botiga() {}
}
```
Fixeu-vos que hem emprat `@Component` per tal d'especificar que aquesta classe és un bean.
Dins aquesta mateixa carpeta crearem una altre bean anomenat Principal el qual contindrà un mètode anomenat init. Aquest mètode ens mostrarà la llista de beans presents al nostre projecte, tant els que hem creat de forma explícita com els ja existents per defecte:
```
package com.iticbcn.iticbcn.projecteexemple.configanotacions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import jakarta.annotation.PostConstruct;
@Component
public class Principal {
@Autowired
private ApplicationContext appctx;
@PostConstruct
public void init() {
for (String s:appctx.getBeanDefinitionNames()) {
System.out.println("Beans >>>>" + s);
}
}
}
```
Fixeu-vos que utilitzem dues anotacions interessant: d'una banda `@Autowired` per dir que les dependències s'injecten automàticament i d'altra `@PostContruct` per dir que s'executi el mètode un cop el bean s'hagi inicialitzat completament.
Ara tot seguit si executem el projecte veurem com ens apareixen els beans que hem creat explícitament:
```
Beans >>>>botiga
Beans >>>>principal
```
##### L'estereotip @Component
És un estereotip genèric per qualsevol component administrat per Spring.
Són especialitzacions d’`@Component`:
* `@Repository` (estereotip de capa de persistència): Anotació emprada per qualsevol classe que faci el rol de DAO.
* `@Service` (estereotip de capa de servei): Objectes reutilitzables sense estat, emprats per realitzar operacions de lògica de negoci amb altres objectes passats com a paràmetre.
* `@Controller` (estereotip de capa de presentació Spring MVC): El dispatcher fa un scan de classes amb aquesta anotació i detecta els mètodes amb l’anotació @RequestMapping per tal de procedir al mapatge des de la vista cap a altres capes.
##### DI amb Autowired
Com veurem ara l'anotació `@Autowired` ens permetrà fer la injecció de dependències de forma automàtica en les diferents variants com són:
* Per variable d'instància.
* Per constructor.
* Per setter (o per un altre mètode)
###### Autowired amb variable d'instància
Tot seguit crearem una carpeta que anomenarem DIAutowired on ficarem dos nous arxius anomenats Repositori i Servei:
```
package com.iticbcn.iticbcn.projecteexemple.DIautowired;
import org.springframework.stereotype.Repository;
@Repository
public class Repositori {
public void CrearRegistre() {
System.out.println("Inserint registre a l'origen de dades");
}
}
```
```
package com.iticbcn.iticbcn.projecteexemple.DIautowired;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class Servei {
@Autowired
private Repositori Repo;
public void executar() {
Repo.CrearRegistre();
}
}
```
Fixeu-vos com ara a Servei estem injectant Repositori aplicant `@Autowired`
Ara agafem la classe Principal i la treiem de la carpeta configanotations, de tal forma que ara el mètode init executarà el mètode contingut al servei:
```
package com.iticbcn.iticbcn.projecteexemple;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.iticbcn.iticbcn.projecteexemple.DIautowired.Servei;
import jakarta.annotation.PostConstruct;
@Component
public class Principal {
@Autowired
private Servei servei;
@PostConstruct
public void init() {
servei.executar();
}
}
```
Seguint amb la cadena d'injeccions fixeu-vos com hem injectat el servei dins Principal i utilitzem els seus mètodes.
Si executem el resultat serà:
```
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.4.3)
2025-03-13T18:25:32.473+01:00 INFO 18564 --- [projecteexemple] [ main] c.i.i.p.ProjecteexempleApplication
: Starting ProjecteexempleApplication using Java 17.0.1 with PID 18564 (C:\Users\46456715G\Downloads\projecteexemple\projecteexemple\target\classes started by atalens1 in C:\Users\46456715G\Downloads\projecteexemple)
2025-03-13T18:25:32.478+01:00 INFO 18564 --- [projecteexemple] [ main] c.i.i.p.ProjecteexempleApplication
: No active profile set, falling back to 1 default profile: "default"
Inserint registre a l'origen de dades
2025-03-13T18:25:33.550+01:00 INFO 18564 --- [projecteexemple] [ main] c.i.i.p.ProjecteexempleApplication
: Started ProjecteexempleApplication in 1.702 seconds (process running for 2.214)
```
###### Autowired amb constructor
Com alternativa a fer servir aquesta anotació amb les propietats/variables veurem que si bé l'autowired amb constructor ens afegeix línies de codi, els avantatges que té de cara al testing i a la llegibilitat del codi la fan una bona opció per injectar dependències.
En el cas d'haver un únic constructor no és obligatori utilitzar l'anotació, però en qualsevol cas és recomanable fer-ho.
Així, anem ara a la classe Servei i fem els següents canvis:
```
package com.iticbcn.iticbcn.projecteexemple.DIautowired;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class Servei {
//@Autowired
private Repositori Repo;
@Autowired
public Servei(Repositori repo) {
this.Repo = repo;
}
public Servei() {}
public void executar() {
Repo.CrearRegistre();
}
}
```
###### Autowired amb setter
Ja per últim, tornem a la classe Principal i generem un setter per l'objecte repositori, al qual hi afegirem l'anotació `@Autowired`:
```
package com.iticbcn.iticbcn.projecteexemple;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.iticbcn.iticbcn.projecteexemple.DIautowired.Servei;
import jakarta.annotation.PostConstruct;
@Component
public class Principal {
private Servei servei;
@Autowired
public void setServei(Servei servei) {
this.servei = servei;
}
@PostConstruct
public void init() {
servei.executar();
}
}
```
#### Configuració amb fitxer java (Java Config)
Aquesta és una forma alternativa al mecanisme de múltiples anotacions amb Autowired, de tal forma que podem injectar dependències fent servir un o més fitxers de configuració amb dues anotacions (sols dos): `@Configuration` i `@Bean`.
* L'anotació `@Configuration` indica que la classe és una font de definicions de beans. També el podem afegir a diverses classes de configuració.
* Utilitzem l'anotació `@Bean` en un mètode per definir un bean. Si no especifiquem un nom personalitzat, el nom del bean serà el nom del mètode per defecte.
Per entendre com funciona tornem al nostre projecte i creem la carpeta javaconfigurations (al mateix nivell que les anteriors carpetes).
Dins la carpeta fiquem una classe anomenada PrimerBean amb aquest codi simple:
```
package com.iticbcn.iticbcn.projecteexemple.javaconfigurations;
public class PrimerBean {
public PrimerBean () {}
public void SendMessage() {
System.out.println("Missatge enviat");
}
}
```
I ara fiquem una altra classe anomenada SegonBean on observarem la dependència amb el primer bean:
```
package com.iticbcn.iticbcn.projecteexemple.javaconfigurations;
public class SegonBean {
private PrimerBean primerBean;
public SegonBean(PrimerBean primerBean) {
this.primerBean=primerBean;
}
public void ReceiveMessage() {
primerBean.SendMessage();
System.out.println("Missatge rebut");
}
}
```
Fixeu-vos que fins el moment no hem fet servir cap anotació i aquestes classes són classes java corrents. Per tal que esdevinguin beans crearem una nova classe anomenada JavaConfig (podria dir-se amb qualsevol altre nom, aquest és un exemple) amb el següent codi:
```
package com.iticbcn.iticbcn.projecteexemple.javaconfigurations;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class JavaConfig {
@Bean
public PrimerBean pbean() {
return new PrimerBean();
}
@Bean
public SegonBean sbean() {
return new SegonBean(pbean());
}
}
```
El que hem fet és declarar que les classes PrimerBean i SegonBean són beans d'spring fent servir `@Bean`. Per tal que la classe JavaConfig sigui en efecte una classe de configuració cal ficar-li l'anotació `@Configuration`.
En aquest punt, si volem injectar SegonBean podem fer-ho de diferents maneres.
1. Modificant la classe ProjecteexempleApplication (on hi és el main) d'aquesta manera:
```
package com.iticbcn.iticbcn.projecteexemple;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import com.iticbcn.iticbcn.projecteexemple.javaconfigurations.SegonBean;
@SpringBootApplication
public class ProjecteexempleApplication {
public static void main(String[] args) {
ApplicationContext appctx =
SpringApplication.run(ProjecteexempleApplication.class, args);
SegonBean sbean = appctx.getBean(SegonBean.class);
sbean.ReceiveMessage();
}
}
```
On fixeu-vos que fem una instància d'ApplicationContext i a partir d'aquesta obtenim el bean i executem el mètode. Aquesta seria la resposta:
```
Missatge enviat
Missatge rebut
```
2. Si no volem embrutar la classe on està el main tenim altres alternatives com per exemple fer un nova classe que implementarà la interfície ApplicationListener:
```
package com.iticbcn.iticbcn.projecteexemple.javaconfigurations;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
public class AppInitializer implements ApplicationListener<ContextRefreshedEvent> {
private final SegonBean segonBean;
public AppInitializer(SegonBean segonBean) {
this.segonBean = segonBean;
}
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
segonBean.ReceiveMessage();
}
}
```
Caldrà declarar-la com a bean dins l'arxiu JavaConfig:
```
package com.iticbcn.iticbcn.projecteexemple.javaconfigurations;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextRefreshedEvent;
@Configuration
public class JavaConfig {
@Bean
public PrimerBean pbean() {
return new PrimerBean();
}
@Bean
public SegonBean sbean() {
return new SegonBean(pbean());
}
@Bean
public ApplicationListener<ContextRefreshedEvent> appInitializer() {
return new AppInitializer(sbean());
}
}
```
I d'aquesta forma deixem ProjecteexempleApplication com estava a l'inici:
```
package com.iticbcn.iticbcn.projecteexemple;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ProjecteexempleApplication {
public static void main(String[] args) {
SpringApplication.run(ProjecteexempleApplication.class, args);
}
```
Una altra opció més, però que haureu d'explorar i investigar pel vostre compte, és crear una classe que implemente la interfície InitializingBean. Com s'hauria de fer?
### Àmbit dels beans. Cicle de vida d'un bean
De forma predeterminada cada bean injectat és un **singleton**, és a dir, una instància única que s'emmagatzema en el contenidor d'inversió de control (IoC) i que és compartida per totes les classes en les quals s'injecta cada bean. Aquesra instància única es crea quan s'arrenca el contenidor IoC i es destrueix quan s'apaga.
Exemple: imaginem un bean d'un servei que conté una o més regles de negoci, les quals s'han de validar en diferents punts de l'aplicació. El fet que l'àmbit d'aquest servei sigui singleton fa que aquesta instància única d'aquest servei pugui ser injectada a requeriment de cada classe durant l'execució de l'aplicació, sense necessitat de generar noves instàncies del mateix servei/bean.
No obstant és possible fer que un mateix bean injectat a diferents classes pugui tenir instàncies diferents. En aquests casos a diferència de l'àmbit predeterminat singleton, el contenidor IoC no s'encarrega de destruir aquestes instàncies i cal fer-ho de forma explícita.
Amb quina finalitat voldríem una instància diferent del mateix bean? doncs en aquells casos on es requereixen objectes que no es puguin compartir entre múltiples injeccions o components que han de tenir una vida temporal mentre s'executa l'aplicació (i que el fet que siguin singleton fa que romanguin més temps del necessari).
Així si volem que un bean no tingui l'àmbit sigleton podem utilitzar l'anotació `@Scope`("prototype"). Per veure com funciona tornem a la carpeta DIAutowired que havíem creat en exemples anteriors i modificarem la classe Repositori per afegir-li aquesta anotació d'Scope:
```
package com.iticbcn.iticbcn.projecteexemple.DIautowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;
@Repository
@Scope("prototype")
public class Repositori {
public void CrearRegistre() {
System.out.println("Inserint registre a l'origen de dades");
}
}
```
Ara crearem dos serveis nous, serveiA i serveiB que injectaran a Repositori cadascun (i faran el mateix):
```
package com.iticbcn.iticbcn.projecteexemple.DIautowired;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ServeiA {
Repositori Repo;
public ServeiA() {}
@Autowired
public ServeiA(Repositori repo) {
this.Repo = repo;
}
public void executar() {
System.out.println("Executant servei A");
Repo.CrearRegistre();
}
}
```
```
package com.iticbcn.iticbcn.projecteexemple.DIautowired;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ServeiB {
Repositori Repo;
public ServeiB() {}
@Autowired
public ServeiB(Repositori repo) {
this.Repo = repo;
}
public void executar() {
System.out.println("Executant servei B");
Repo.CrearRegistre();
}
}
```
Ara tornem a la classe Principal i la deixem com segueix:
```
package com.iticbcn.iticbcn.projecteexemple.DIautowired;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import jakarta.annotation.PostConstruct;
@Component
public class Principal {
private ApplicationContext appctx;
private ServeiA serveiA;
private ServeiB serveiB;
@Autowired
public void setApplicationContext(ApplicationContext appctx) {
this.appctx = appctx;
}
@Autowired
public void setServeiA(ServeiA serveiA) {
this.serveiA = serveiA;
}
@Autowired
public void setServeiB(ServeiB serveiB) {
this.serveiB = serveiB;
}
@PostConstruct
public void init() {
for (String s:appctx.getBeanDefinitionNames()) {
System.out.println("Beans >>>>" + s);
}
System.out.println(serveiA.Repo);
System.out.println(serveiB.Repo);
serveiA.executar();
serveiB.executar();
}
}
```
La idea és, primerament, mostrar els beans a partir de l'ApplicationContext (tal i com ja vam fer a l'inici) i veure que en efecte ens apareixen aquests beans injectats al contenidor:
```
Beans >>>>principal
Beans >>>>repositori
Beans >>>>serveiA
Beans >>>>serveiB
```
En segon lloc, mitjançant `serveiA.Repo` i `serveiB.Repo` observem que en efecte les referències associades a cada instància son diferents. Això és degut a fer servir l'scope prototype:
```
com.iticbcn.iticbcn.projecteexemple.DIautowired.Repositori@6ab72419
com.iticbcn.iticbcn.projecteexemple.DIautowired.Repositori@3aacf32a
```
Si ara tornem a repositori i treiem l'scope prototype (i fer que sigui un singleton per defecte), a l'executar veurem el següent:
```
com.iticbcn.iticbcn.projecteexemple.DIautowired.Repositori@2ef8a8c3
com.iticbcn.iticbcn.projecteexemple.DIautowired.Repositori@2ef8a8c3
```
És a dir, que la instància és compartida.
Altres àmbits a més de prototype són: Request, Session, Application i WebSocket. Per no ser extensos no parlarem encara d'ells.
Per altra banda i tornant al que és el cicle de vida d'un bean, des de que s'inicialitza fins que es destrueix, són interessants les anotacions `@PostConstruct` i `@PreDestroy`. De fet aquestes anotacions no són pròpies d'spring, sinó més aviat de java.
Com ja hem vist en diferents exemples `@PostConstruct` indica que aquell mètode amb aquesta anotació s'ha d'executar un cop el bean on es troba ja té totes les dependències resoltes, totes les propietats injectades, etc. Era el cas de la classe Principal i el mètode que hem anomenat init:
```
@PostConstruct
public void init() {
for (String s:appctx.getBeanDefinitionNames()) {
System.out.println("Beans >>>>" + s);
}
System.out.println(serveiA.Repo);
System.out.println(serveiB.Repo);
serveiA.executar();
serveiB.executar();
}
```
Quan un mètode qualsevol porta l'anotació `@PreDestroy` vol dir que s'haurà d'executar abans que el bean que el conté procedeixi a ser destruït:
```
@PreDestroy
public void end() {
System.out.println("Aquest bean va a ser destruït");
}
```
Si modifiquem la classe Principal per afegir aquest codi, veurem aquest resultat:
```
Executant servei A
Inserint registre a l'origen de dades
Executant servei B
Inserint registre a l'origen de dades
2025-03-15T16:15:39.559+01:00 INFO 15964 --- [projecteexemple] [ main] c.i.i.p.ProjecteexempleApplication : Started ProjecteexempleApplication in 1.054 seconds (process running for 1.343)
Aquest bean va a ser destruït
```
On la sortida que tenia el mètode end() apareix en darrer lloc.
Per veure la necessitat o no de fer servir aquestes anotacions i interaccionar amb el cicle de vida d'un bean, caldrà veure les necessitats que tinc, per exemple, fer una sèrie d'accions inicials quan arranquem l'aplicació o bé buidar manualment beans d'scope prototype quan l'aplicació finalitzi.