A Coreia do Sul é uma “república do Spring”?
Se você quer conseguir emprego como desenvolvedor backend na Coreia, existe uma pergunta da qual é quase impossível escapar: “Você sabe usar Spring?”
Basta entrar em sites de vagas para ver: em nove de cada dez anúncios aparece explicitamente “experiência com Spring Boot” nos requisitos. Não é à toa que existe até a expressão “república do Spring”. Na época da faculdade, eu achava que isso era só moda.
“Não dá para simplesmente escrever em Java? Por que usar justamente esse Spring pesado?” “Node.js ou Python (Django) não são mais fáceis?”
Mas quando entrei no mercado e vivi projetos grandes de verdade, entendi. Spring não era uma simples tendência, e sim uma bancada padrão de trabalho refinada por inúmeros desenvolvedores experientes para que sistemas corporativos enormes e complexos pudessem ser construídos de forma segura e rápida.
Esta série fala justamente sobre como erguer, sobre essa bancada padrão, um castelo que não desmorona: um Monolith.
Framework: por que você não pode fazer tudo do seu jeito
Antes de entrar de vez na parte técnica, precisamos acertar uma coisa. O que exatamente é um framework? E o que o diferencia de uma biblioteca?
Eu já tinha mencionado isso rapidamente na série Re: Booting, mas a diferença decisiva entre os dois gira em torno de uma única pergunta: quem está com o controle nas mãos?
Spring é um framework. Então usar Spring é quase como fazer uma promessa: “vou deixar um pouco de lado meu estilo pessoal e seguir o jeito que o Spring manda”. O coração desse “fazer do jeito que o Spring manda” é exatamente o tema de hoje: Inversion of Control (IoC).
“Por favor, parem de usar new o tempo todo”
A primeira regra dessa promessa foi um choque para mim. Ela basicamente dizia: não use new, um dos elementos mais básicos do Java.
Na faculdade era algo óbvio: se eu precisava de um objeto, eu escrevia MemberService service = new MemberService();. Se preciso de alguma coisa, eu mesmo crio e uso. O que haveria de estranho nisso?
Mas depois que entrei em uma empresa e abri um projeto Spring Boot, não encontrava a palavra-chave new em lugar nenhum. No lugar dela, vi anotações estranhas como @Autowired e @RequiredArgsConstructor espalhadas por todo lado.
“Espera, se ninguém criou esse objeto, então como esse método está sendo chamado? Isso realmente funciona?”
Quando perguntei isso a um desenvolvedor sênior, a resposta soou irritantemente vaga. “O Spring Container injeta isso sozinho, então a gente não precisa criar manualmente. Aliás, se você usar new direto, depois a manutenção vai ficar bem mais difícil.”
Eu não conseguia aceitar aquilo. Eu era o dono do código que escrevia, então por que nem mesmo criar um objeto eu podia fazer livremente? Parecia quase uma ditadura do Spring.

O chef e o gerente dos ingredientes (IoC & DI)
Para entender por que essa regra que parece autoritária é necessária, vamos trocar a metáfora e ir para a cozinha de um restaurante.
1. O jeito tradicional (eu mando)
Eu sou um chef, uma Class. Para cozinhar, preciso de uma faca, uma Dependency.
2. O jeito do Spring (Spring manda)
Eu continuo sendo o chef. Mas desta vez existe um gerente responsável pelos ingredientes e ferramentas: o Spring Container.
Ou seja, em vez de eu mesmo gerenciar os recursos de que preciso, algo externo os gerencia e me entrega. Isso é Inversion of Control (IoC: Inversion of Control), e a técnica concreta usada para fazer isso se chama Dependency Injection (DI).

[Code Verification] Por que new é perigoso?
Só falar não faz a ficha cair de verdade. Vamos comparar isso diretamente no código. Imagine que estamos construindo um sistema de pagamento com cartão.
1. Exemplo ruim: criação direta (acoplamento forte)
public class PaymentService {
// Eu mesmo escolhi e criei um Samsung Card (usando new)
private final SamsungCard card = new SamsungCard();
public void pay() {
card.payment(); // Pagamento apenas com Samsung Card
}
}
O problema: um dia o chefe diz: “Vamos trocar para Hyundai Card, porque a taxa é mais barata!” Nesse momento eu teria de abrir o código de PaymentService e substituir todo SamsungCard por HyundaiCard. E se esse código estiver em cem lugares diferentes? Hora extra garantida.
2. Exemplo bom: dependency injection (acoplamento frouxo)
public class PaymentService {
private final Card card; // Nao especifique uma bandeira concreta (use a interface)
// Injecao por construtor: confiar que alguem de fora vai entregar o cartao
public PaymentService(Card card) {
this.card = card;
}
public void pay() {
card.payment();
}
}
Agora o PaymentService não se importa mais com qual implementação concreta de cartão foi entregue a ele.
Esse é o coração do que na prática se chama “código fácil de manter”, ou princípio OCP. E é exatamente essa flexibilidade que faz tanta gente usar Spring Boot.
Spring Container: um hotel para objetos
Então quem é esse “gerente” que cria os objetos e os distribui? É justamente o Spring Container.
No momento em que iniciamos o servidor Spring Boot com run, muita coisa acontece por baixo dos panos.
Nosso trabalho é só colar na classe um adesivo dizendo “por favor, gerencie isso”, por exemplo com @Service. O resto é por conta do Spring, como um grande gerente de hotel organizando todos os hóspedes.
Conselho prático: use injeção por construtor
O Spring oferece várias formas de injetar dependências: field injection com @Autowired, setter injection e constructor injection. Mas em projetos reais quase sempre se recomenda constructor injection. É o padrão normalmente usado junto com o @RequiredArgsConstructor do Lombok.
@Service
@RequiredArgsConstructor // Isto gera automaticamente a injecao por construtor.
public class OrderService {
// pode se usar final, por isso e seguro
private final PaymentService paymentService;
}
Por quê?
Para encerrar: não um mágico, mas um maestro
No começo, eu rejeitava o Spring porque parecia que ele manipulava meu código como queria. Hoje vejo de outra forma. Spring não é um ditador que me atormenta, mas um maestro competente que organiza relações complexas entre objetos.
Graças a isso, gasto menos tempo pensando “que objeto eu preciso criar?” e consigo me concentrar mais em “como eu construo a lógica de negócio com esse objeto?”. Provavelmente é por isso que tantos desenvolvedores na Coreia continuam tão fiéis ao Spring.
Agora já entregamos ao Spring o controle da gestão dos objetos. O servidor está pronto para subir. Mas uma aplicação web não roda sozinha: ela precisa conversar com o frontend. Na época do PHP era confortável porque HTML e código viviam no mesmo arquivo. Então por que hoje se separa o frontend, com Vue ou React, do backend? E por que aparece um erro vermelho de CORS assim que você tenta conectar os dois?
No próximo texto, vamos olhar para a mudança da arquitetura web, SSR vs CSR, e para a verdadeira identidade do CORS, a barreira que fica entre os dois.