#spring-boot #kotlin
Вопрос:
Я пытаюсь создать и запустить приложение spring boot, используя язык kotlin. Я исследовал некоторые похожие вопросы, но не смог создать свое приложение. Вывод ошибок: Параметр 0 конструктора в файле com.github.raketa92.mailservice.service.Для службы электронной почты требовался компонент типа «com.github.raketa92.mailservice.repository.MailRepository», который не удалось найти. Рассмотрите возможность определения компонента типа «com.github.raketa92.mailservice.repository.MailRepository» в вашей конфигурации. Я нашел репозиторий github, где такой код создается и успешно выполняется.
Вот мой файл репозитория:
interface MailRepository : CoroutineCrudRepository<Email, Long>{
@Query("SELECT * FROM email WHERE messageId = :messageId")
suspend fun getEmailByMessageId(messageId: Int): Email?
@Query("UPDATE email set statusId = :statusId where id = :id")
suspend fun updateStatus(statusId: Int, id: Long): Email
}
Вот мое служебное досье:
package com.github.raketa92.mailservice.service
import com.github.raketa92.mailservice.model.Email
import com.github.raketa92.mailservice.repository.MailRepository
import kotlinx.coroutines.flow.Flow
import org.springframework.mail.SimpleMailMessage
import org.springframework.mail.javamail.JavaMailSender
import org.springframework.stereotype.Service
@Service
class EmailService(
private val mailRepository: MailRepository,
private val javaMailSender: JavaMailSender
)
{
fun sendMail(email: Email) {
val message = SimpleMailMessage()
message.setSubject(email.subject)
message.setText(email.message!!)
message.setTo(email.to)
message.setFrom("test@mail.com")
javaMailSender.send(message)
println("email sent")
}
suspend fun getAllEmails(): Flow<Email> = mailRepository.findAll()
suspend fun getEmailById(id: Long): Email? = mailRepository.findById(id)
suspend fun getEmailByMessageId(messageId: Int): Email? = mailRepository.getEmailByMessageId(messageId)
suspend fun createEmail(email: Email): Email = mailRepository.save(email)
suspend fun updateStatus(statusId: Int, id: Long): Email = mailRepository.updateStatus(statusId, id)
}
Ответ №1:
У вас EmailService
есть пружина @Service
, поэтому Весна создаст ее экземпляр при запуске.
Но его конструктору нужен MailRepository
экземпляр. И вы не сказали ему, откуда его взять, поэтому он выдает ошибку времени выполнения, которую вы видели.
Обычный способ рассказать Spring об интерфейсе репозитория-это аннотировать его как @Repository
; затем Spring знает, что нужно создать экземпляр (синтетического подкласса, реализующего) этот интерфейс.
Комментарии:
1. Спасибо за ваш ответ. Я пытался аннотировать репозиторий с помощью @Repository, но это не помогло, показывает ту же ошибку.
2. Вы находитесь
MailRepository
в том же пакете, что и ваш класс приложений верхнего уровня, или в подпакете? Это иерархия, в которой по умолчанию выполняется поиск Spring, поэтому вам нужно либо убедиться, что нужные вам классы находятся там, либо указать, где искать (с помощью одного из параметров@SpringBootApplication
или связанной аннотации в вашем классе верхнего уровня).3. файл репозитория находится в подпакете, но я также попытался переместить его на тот же уровень, что и класс приложения, но все равно получил ту же ошибку. Интересно, какие ситуации могут вызвать такого рода ошибки, может быть, если я буду искать в этом направлении, я смогу что-то найти.