O que é um Bean?

No Spring, um Bean é simplesmente um objeto que o container do Spring gerencia.
Ou seja, em vez de você instanciar suas classes manualmente com new, o Spring cuida disso por você.

Exemplo sem Spring:

public class SemBeanService {
    public String mensagem() {
        return "Olá!";
    }
}

public class App {
    public static void main(String[] args) {
        SemBeanService service = new SemBeanService();
        System.out.println(service.mensagem());
    }
}

Exemplo com Spring:

@Component
public class ComBeanService {
    public String mensagem() {
        return "Olá!";
    }
}

@Component
public class ComBeanController {
    private final ComBeanService service;

    @Autowired
    public ComBeanController(ComBeanService service) {
        this.service = service;
    }

    public void exibir() {
        System.out.println(service.mensagem());
    }
}

Como declarar Beans:

Qualquer classe anotada com @Component, @Service, @Repository ou @Controller será registrada como Bean.

import org.springframework.stereotype.Component;

@Component
public class PagamentoService {
    public void pagar() {
        System.out.println("Pagamento feito");
    }
}

Ou você pode usar o @Bean em uma classe @Configuration

@Configuration
public class AppConfig {

    @Bean
    public EmailService emailService() {
        return new EmailService();
    }
}

Ciclo de Vida de um Bean

Você pode executar ações quando o Bean for criado @PostConstruct ou destruído @PreDestroy.

@Component
public class ConexaoBanco {

    @PostConstruct
    public void iniciar() {
        System.out.println("inicio");
    }

    @PreDestroy
    public void fechar() {
        System.out.println("fim");
    }
}

Escopos de Beans

Por padrão, os Beans do Spring são singleton, mas pode ser trocado com @Scope:

singleton: uma instância única para toda a aplicação;
prototype: uma nova instância a cada vez que for solicitado;
request: uma instância por requisição HTTP;
session:uma instância por sessão de usuário.

Nesse exemplo, se você pedir esse Bean duas vezes, terá dois objetos diferentes:

@Component
@Scope("prototype")
public class Usuario {
    public Usuario() {
        System.out.println("Novo usuário");
    }
}