Spring — IOC, DI e AUTOWIRED -> Desconstruindo mitos!
Fala glr, e ai suave ? Então, é noixxx!
hoje quero tentar esclarecer algo que aconteceu no spring framework 4.3 (em 2016 faz tempo) e que aparentemente tem gerado uma interpretação digamos, confusa(até hoje =/). Pra isso vou falar um pouquinho de Ioc e DI para chegarmos até nosso amigo autowired, bora lá.
Recentemente tenho visto pessoas relevantes da nossa área falando que o Spring “desencorajou o uso de autowired e passou a recomendar a injeção pelo construtor, apartir da versão 4.3”.
Para tentar por luz sobre a questão vou trazer nosso primeiro elemento, o Ioc principle ou princípio da inversão de controle e diria mais, conhecido popurlamente como DI (Injeção de dependência). Veja o que o spring fala sobre:
“This chapter covers the Spring Framework implementation of the Inversion of Control (IoC) [1]principle. IoC is also known as dependency injection (DI). It is a process whereby objects define their dependencies, that is, the other objects they work with, only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse, hence the name Inversion of Control (IoC), of the bean itself controlling the instantiation or location of its dependencies by using direct construction of classes, or a mechanism such as the Service Locator pattern.”
O container do Ioc no spring tem sua representação pela interface ApplicationContext que por sua vez pode ser configurada por XML, anotações java ou código java. Isso quem diz é o proprio Spring como pode ser visto abaixo:
“The interface org.springframework.context.ApplicationContext represents the Spring IoC container and is responsible for instantiating, configuring, and assembling the aforementioned beans. The container gets its instructions on what objects to instantiate, configure, and assemble by reading configuration metadata. The configuration metadata is represented in XML, Java annotations, or Java code. It allows you to express the objects that compose your application and the rich interdependencies between such objects.”
É aqui que entra a anotação “autowired”. Ela faz parte do que o spring chama de “Annotation-based container configuration”, configuração de container baseada em annotações. Bora entender melhor pelas palavras do spring:
“Instead of using XML to describe a bean wiring, the developer moves the configuration into the component class itself by using annotations on the relevant class, method, or field declaration. As mentioned in the section called “Example: The RequiredAnnotationBeanPostProcessor”, using a BeanPostProcessor in conjunction with annotations is a common means of extending the Spring IoC container. For example, Spring 2.0 introduced the possibility of enforcing required properties with the @Required annotation. Spring 2.5 made it possible to follow that same general approach to drive Spring’s dependency injection. Essentially, the @Autowired annotation provides the same capabilities as described in Section 5.4.5, “Autowiring collaborators” but with more fine-grained control and wider applicability. Spring 2.5 also added support for JSR-250 annotations such as @PostConstruct, and @PreDestroy. Spring 3.0 added support for JSR-330 (Dependency Injection for Java) annotations contained in the javax.inject package such as @Inject and @Named. ”
Agora que sabemos o que é Ioc, DI e autowired, vamos ver o que o spring trouxe no 4.3:
“if you forget the @Autowired annotation on the constructor, the container will throw an exception looking for a default constructor, unless you explicitly indicate autowire mode ‘constructor’ in your bean definition setup (e.g. in an XML <bean>).
So as of 4.3, you no longer need to specify an explicit injection annotation in such a single-constructor scenario. This is particularly elegant for classes which otherwise do not carry any container annotations at all, for example when programmatically registered.”
Fica bastante claro que o spring otimizou as configurações de container para “Implicit constructor injection for single-constructor scenarios” como ele mesmo fala. Assim, não se trata de usar “construtor” ou “autowired”, ou “desencorajar o uso de autowired” porquê afinal, você sempre pode configurar o container via XML, anotações ou código. O que ele agregou foi que em casos “obvios” ou seja, quando o ou os beans que a classe precisa são listados no construtor como argumentos e a classe possue apenas esse construtor, o spring vai injeta-los implicitamente, tirando a necessidade de quaisquer configuração adcional para isso.
Existem varios aspectos para decidir como vai se trabalhar com DI no spring e determinar o uso de anotações ou outra forma de configuração do container do spring context e se você quiser se aprofundar mais, pode acessar a doc oficial deles e fundamentar suas decisões tecnicamente. Os links estão mais abaixo, no final do artigo.
Bem é isso, mais um mito descontruido e bora dividir conhecimento pois quando a gente divide conhecimento a gente ta multiplicando.
vlw flw e tmj \m/
Links e referências:
https://spring.io/blog/2016/03/04/core-container-refinements-in-spring-framework-4–3