Olá. Estou desenvolvendo uma API com Spring em Java.
Nesse momento, estou desenvolvendo mais especificamente um serviço de envio automático de e-mails.
Para isso, criei suas classes de serviço chamadas MockEmailService(apenas para testes) e SmtpEmailService(para produção).
Na classe que implementa o profile de desenvolvimento ( DevConfig
), defini um @Bean
para fazer a injeção de dependência da classe SmtpEmailService, na classe de serviço PedidoService
.
Porém, está sendo apresentado o seguinte erro:
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
[2m2021-09-27 13:36:50.290[0;39m [31mERROR[0;39m [35m5236[0;39m [2m---[0;39m [2m[ restartedMain][0;39m [36mo.s.b.d.LoggingFailureAnalysisReporter [0;39m [2m:[0;39m
***************************
APPLICATION FAILED TO START
***************************
Description:
Field emailService in com.mateuussilvapb.cursomc.services.PedidoService required a bean of type 'com.mateuussilvapb.cursomc.services.EmailService' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.mateuussilvapb.cursomc.services.EmailService' in your configuration.
Classe SmtpEmailService:
package com.mateuussilvapb.cursomc.services;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
public class SmtpEmailService extends AbstractEmailService {
@Autowired
private MailSender mailSender;
// Objeto que será usado para mostrar o e-mail no LOG do servidor
private static final Logger LOG = LoggerFactory.getLogger(SmtpEmailService.class);
@Override
public void sendEmail(SimpleMailMessage msg) {
LOG.info("Simulando envio de e-mail...");
mailSender.send(msg);
LOG.info("E-mail enviado!");
}
}
Classe PedidoService
package com.mateuussilvapb.cursomc.services;
import java.util.Date;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.mateuussilvapb.cursomc.domain.ItemPedido;
import com.mateuussilvapb.cursomc.domain.PagamentoComBoleto;
import com.mateuussilvapb.cursomc.domain.Pedido;
import com.mateuussilvapb.cursomc.domain.enums.EstadoPagamento;
import com.mateuussilvapb.cursomc.repositories.ItemPedidoRepository;
import com.mateuussilvapb.cursomc.repositories.PagamentoRepository;
import com.mateuussilvapb.cursomc.repositories.PedidoRepository;
import com.mateuussilvapb.cursomc.services.exceptions.ObjectNotFoundException;
@Service
public class PedidoService {
/*
* Quando se declara uma dependência e é acrescentado a anotação 'Autowired', a
* dependência é instanciada automaticamente pelo Spring.
*/
@Autowired
private PedidoRepository repo;
@Autowired
private BoletoService boletoService;
@Autowired
private PagamentoRepository pagamentoRepository;
@Autowired
private ProdutoService produtoService;
@Autowired
private ItemPedidoRepository itemPedidoRepository;
@Autowired
private ClienteService clienteService;
@Autowired
private EmailService emailService;
public Pedido find(Integer id) {
Optional<Pedido> obj = repo.findById(id);
return obj.orElseThrow(() -> new ObjectNotFoundException(
"Objeto não encontrado! ID: " + id + ". " + "Tipo: " + Pedido.class.getName()));
}
@Transactional
public Pedido insert(Pedido obj) {
obj.setId(null);
obj.setInstante(new Date());
obj.setCliente(clienteService.find(obj.getCliente().getId()));
obj.getPagamento().setEstado(EstadoPagamento.PENDENTE);
obj.getPagamento().setPedido(obj);
if (obj.getPagamento() instanceof PagamentoComBoleto) {
PagamentoComBoleto pagto = (PagamentoComBoleto) obj.getPagamento();
boletoService.preencherPagamentoComBoleto(pagto, obj.getInstante());
}
obj = repo.save(obj);
pagamentoRepository.save(obj.getPagamento());
for (ItemPedido ip : obj.getItens()) {
ip.setDesconto(0.0);
ip.setProduto(produtoService.find(ip.getProduto().getId()));
ip.setPreco(ip.getProduto().getPreco());
ip.setPedido(obj);
}
itemPedidoRepository.saveAll(obj.getItens());
emailService.sendOrderConfirmationEmail(obj);
return obj;
}
}
Classe de implementação do profile de configuração dev ( DevConfig
)
package com.mateuussilvapb.cursomc.config;
import java.text.ParseException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import com.mateuussilvapb.cursomc.services.DBService;
import com.mateuussilvapb.cursomc.services.EmailService;
import com.mateuussilvapb.cursomc.services.SmtpEmailService;
@Configuration
@Profile("dev")
public class DevConfig {
@Autowired
private DBService dbService;
@Value("${spring.jpa.hibernate.ddl-auto}")
private String strategy;
@Bean
public boolean instantiateDatabase() throws ParseException {
if (!"create".equals(strategy)) {
return false;
}
dbService.instantiateTestDatabase();
return true;
}
@Bean
public EmailService emailService() {
return new SmtpEmailService();
}
}
Classe EmailService
package com.mateuussilvapb.cursomc.services;
import org.springframework.mail.SimpleMailMessage;
import com.mateuussilvapb.cursomc.domain.Pedido;
public interface EmailService {
void sendOrderConfirmationEmail(Pedido obj);
void sendEmail(SimpleMailMessage msg);
}
A classe anotada com @SpringBootApplication
está no pacote raiz: com.mateuussilvapb.cursomc
:
package com.mateuussilvapb.cursomc;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class CursomcApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(CursomcApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
}
}
O profile de dev
está ativo:
spring.profiles.active=dev
default-sender=mateuussilvapb@gmail.com
default-recipient=mateuussilvapb@gmail.com
# No JDBC URL: jdbc:h2:file:~/test
Só para deixar mais claro: A aplicação está informando que não está localizando um @Bean
que implemente o serviço EmailService
, porém o @Bean
está definido na classe de configuração DevConfig
Tentei, apesar do meu problema não estar no pacote de repositórios, utilizar o @EnableJpaRepositories
, mas não funcionou. Andei pesquisando a respeito, mas os problemas envolvem principalmente o pacote de repositórios.
Quem puder ajudar, fico grato.