Ошибка при создании bean-компонента с именем webSecurityConfig: неудовлетворенная зависимость, выраженная в поле userSevice
Я хотел сделать рассылку писем пользователям по электронной почте и активировать учетную запись на Spring Boot. И когда я запускаю приложение, оно выдает следующую ошибку:
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-03-03 11:40:31.737 ERROR 10104 --- [ restartedMain] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webSecurityConfig': Unsatisfied dependency expressed through field 'userSevice'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userSevice': Unsatisfied dependency expressed through field 'userRepo'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepo' defined in com.example.eight.repo.UserRepo defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract com.example.eight.models.User com.example.eight.repo.UserRepo.findbyActivationCode(java.lang.String)! No property findbyActivationCode found for type User!
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:643) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1415) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:608) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:531) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~[spring-beans-5.3.3.jar:5.3.3]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:923) ~[spring-context-5.3.3.jar:5.3.3]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:588) ~[spring-context-5.3.3.jar:5.3.3]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144) ~[spring-boot-2.4.2.jar:2.4.2]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:767) [spring-boot-2.4.2.jar:2.4.2]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) [spring-boot-2.4.2.jar:2.4.2]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:426) [spring-boot-2.4.2.jar:2.4.2]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:326) [spring-boot-2.4.2.jar:2.4.2]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1311) [spring-boot-2.4.2.jar:2.4.2]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300) [spring-boot-2.4.2.jar:2.4.2]
at com.example.eight.EightApplication.main(EightApplication.java:11) [classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_121]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_121]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_121]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_121]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-2.4.2.jar:2.4.2]
WebSecurityConfig.java
package com.example.eight.config;
import com.example.eight.service.UserSevice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserSevice userSevice;
@Bean
protected PasswordEncoder getPasswordEncoder(){
return new BCryptPasswordEncoder(8);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login", "/registration", "/static/**", "/activate/*").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userSevice)
.passwordEncoder(NoOpPasswordEncoder.getInstance());
}
}
UserService.java
package com.example.eight.service;
import com.example.eight.models.Role;
import com.example.eight.models.User;
import com.example.eight.repo.UserRepo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.thymeleaf.util.StringUtils;
import java.util.Collections;
import java.util.UUID;
@Service
public class UserSevice implements UserDetailsService {
@Autowired
private UserRepo userRepo;
@Autowired
private MailSender mailSender;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return userRepo.findByUsername(username);
}
public boolean addUser(User user){
User userFromDb = userRepo.findByUsername(user.getUsername());
if (userFromDb != null){
return false;
}
user.setActive(true);
user.setRoles(Collections.singleton(Role.USER));
user.setActivationCode(UUID.randomUUID().toString());
userRepo.save(user);
if (!StringUtils.isEmpty(user.getEmail())){
String message = String.format(
"Hello, %s! \n"+
"Welcome to Spring. Please, visit next link: http://localhost:8080/activate/%s",
user.getUsername(),
user.getActivationCode()
);
mailSender.send(user.getEmail(), "Activation code", message);
}
return true;
}
public boolean activateUser(String code){
User user = userRepo.findbyActivationCode(code);
if(user == null){
return false;
}
user.setActivationCode(null);
userRepo.save(user);
return false;
}
}
Repository: UserRepo.java
package com.example.eight.repo;
import com.example.eight.models.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepo extends JpaRepository<User, Long> {
User findByUsername(String username);
User findbyActivationCode(String code);
}
MailSender.java
package com.example.eight.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
@Service
public class MailSender {
@Autowired
private JavaMailSender mailSender;
@Value("${spring.mail.username}")
private String username;
public void send(String emailTo, String subject, String message){
SimpleMailMessage mailMessage = new SimpleMailMessage();
mailMessage.setFrom(username);
mailMessage.setTo(emailTo);
mailMessage.setSubject(subject);
mailMessage.setText(message);
mailSender.send(mailMessage);
}
}
MailConfig.java
package com.example.eight.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import java.util.Properties;
@Configuration
public class MailConfig {
@Value("${spring.mail.host}")
private String host;
@Value("${spring.mail.username}")
private String username;
@Value("${spring.mail.password}")
private String password;
@Value("${spring.mail.port}")
private int port;
@Value("${spring.mail.protocol}")
private String protocol;
@Value("${mail.debug}")
private String debug;
@Bean
public JavaMailSender getMailSender(){
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
javaMailSender.setHost(host);
javaMailSender.setPort(port);
javaMailSender.setUsername(username);
javaMailSender.setPassword(password);
Properties properties = javaMailSender.getJavaMailProperties();
properties.setProperty("mail.transport.protocol",protocol);
properties.setProperty("mail.debug", debug);
return javaMailSender;
}
}
Ответы (1 шт):
Автор решения: lampa
→ Ссылка
@Repository
public interface UserRepo extends JpaRepository<User, Long> {
User findByUsername(String username);
User findbyActivationCode(String code);
}
Синтаксическая ошибка в findbyActivationCode, By должно начинаться с заглавной буквы.