Como instanciar uma classe no Spring Boot sem new()
- #Spring Boot / Spring Framework
Neste artigo eu vou mostrar pra vcs como o Spring gerencia a instanciação de suas classes usando o IoC container. O IoC container cria um objeto da classe especificada e também injeta todos os objetos de dependência por meio de um construtor, uma propriedade ou um método em tempo de execução e os descarta no momento apropriado.
Isso é feito para que não tenhamos que criar e gerenciar objetos manualmente.
A minha classe é uma classe dummy qualquer:
package com.example.demo;
import org.springframework.stereotype.Component;
public class ClasseQualquer {
private Integer a;
private String b;
@Component
public ClasseQualquer() {
System.out.println("****************************************************************");
System.out.println("****** Classe instanciada na incialização do Spring Boot! ******");
System.out.println("****************************************************************");
}
public void metodoA() {
}
public Integer getA() {
return a;
}
public void setA(Integer a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
}
Como fazer que o IoC gerencie ela? Inserindo o annotation @Component logo antes de sua declaração.
Meu código não tem mais nada apenas a classe que chama o main()
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Esse código é um template gerado pelo próprio Spring Initializer (https://start.spring.io/) e em nenhum momento declarei uma variável para atribuir um new ClasseQualquer()
Rodando a aplicação:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.7.10)
2023-03-28 10:29:40.211 INFO 19232 --- [ main] com.example.demo.DemoApplication : Starting DemoApplication using Java 17.0.4.1 on DESKTOP-HOME with PID 19232 (E:\JAVA\Projetos\exemplo_componente\target\classes started by Acer in E:\JAVA\Projetos\exemplo_componente)
2023-03-28 10:29:40.215 INFO 19232 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to 1 default profile: "default"
2023-03-28 10:29:40.965 INFO 19232 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2023-03-28 10:29:40.973 INFO 19232 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2023-03-28 10:29:40.974 INFO 19232 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.73]
2023-03-28 10:29:41.057 INFO 19232 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2023-03-28 10:29:41.057 INFO 19232 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 800 ms
****************************************************************
****** Classe instanciada na incialização do Spring Boot! ******
****************************************************************
2023-03-28 10:29:41.384 INFO 19232 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2023-03-28 10:29:41.392 INFO 19232 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 1.53 seconds (JVM running for 2.267)
Veja que agora o IoC fez a instanciação de minha classe para usá-la onde quiser. Se vc abrir a declaração do annotation @SpringBootAplication na main class vc vai perceber a seguinte linha de código:
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
É este annotation que informa ao spring boot que ele deve fazer o scan de todas as classes definidas como componentes em seu código.
Ah...e vc deve estar acostumado com as annotations @Controller, @Service, @Repository, eles nada mais são do que aliases para o annotation @Component :)