@ComponentScan使用遇到的问题(仍未解决)

首先交代版本

springboot 2.3.7
java 16

目录结构

目录结构

问题所在

首先可以看到,我的service层是采用接口和实现的形式,在实现类上有@Service注解,接口上没有任何注解。
最开始我没注意,我在调用该service时,本意是想通过@Autowired接口层去使用的,但实际我却是直接调用了实现类,如下:

    @Autowired
    private UserDetailsServiceImpl userDetailsServiceImpl;

在这个时候,我的启动类上没有添加注解:@ComponentScan(“com.example.service”),这个时候程序正常运行,security的验证也是正常的。接口也正常调用。
但是后来我发现自己居然直接调用的是service实现类,那我这个接口不是白写了?所以我把调用那里改成了:

    @Autowired
    private UserDetailsService userDetailsService;

其他没变的情况下,我这时候重新启动程序却报错了:

Description:

Field userDetailsService in com.example.config.security.MyAuthenticationProvider required a bean of type 'com.example.service.UserDetailsService' 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.example.service.UserDetailsService' in your configuration.

看意思就是没有识别到UserDetailsService这个接口咯,那我就百度,然后解决方法就是在启动类上加注解:

@ComponentScan("com.example.service")

加上注解确实程序正常启动了,可以当我登录验证的时候,他却报错了:

2021-05-16 11:20:22.770 ERROR 4904 --- [nio-8080-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception

java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
	at org.springframework.security.crypto.password.DelegatingPasswordEncoder$UnmappedIdPasswordEncoder.matches(DelegatingPasswordEncoder.java:250) ~[spring-security-core-5.3.6.RELEASE.jar:5.3.6.RELEASE]
	at org.springframework.security.crypto.password.DelegatingPasswordEncoder.matches(DelegatingPasswordEncoder.java:198) ~[spring-security-core-5.3.6.RELEASE.jar:5.3.6.RELEASE]
	at org.springframework.security.authentication.dao.DaoAuthenticationProvider.additionalAuthenticationChecks(DaoAuthenticationProvider.java:90) ~[spring-security-core-5.3.6.RELEASE.jar:5.3.6.RELEASE]
	at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:166) ~[spring-security-core-5.3.6.RELEASE.jar:5.3.6.RELEASE]
	at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199) ~[spring-security-core-5.3.6.RELEASE.jar:5.3.6.RELEASE]
	at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:219) ~[spring-security-core-5.3.6.RELEASE.jar:5.3.6.RELEASE]

这个报错的信息应该是没有取到想要的值导致的,应该就是service层没有正常工作。说明前面做的那些步骤没有让service接口正确的被识别。

但是,在控制台里我却发现,他实际上成功调用了service实现,都已经访问到数据库里把数据给取出来了:

Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@574afe8d] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@1810873262 wrapping com.mysql.cj.jdbc.ConnectionImpl@389e377] will not be managed by Spring
==>  Preparing: SELECT * FROM `user` WHERE nickname = ?
==> Parameters: lsjweiyi(String)
<==    Columns: nickname, age, birth_date, phone, email, realname, id_card, role
<==        Row: lsjweiyi, xx, 1996-01-01, xxxxxxx, xxxxxxxxx, xxxx, xxxxxxxxxxxxx, admin
<==      Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@574afe8d]

说明其实service已经成功调用上了,除了这个地方,也没别的地方调用这个方法。但是在后面的程序报错了。

我打断点在service实现类里,确认他确实进入到方法里,可惜这里我再想再别的地方打断点,始终都是没办法生效,这也是我目前还没解决问题,所以没办法探查数据是否正确获取并传给了后面的代码。

到这里,我就可以确认,实际上不是代码的逻辑存在问题, 而是配置和注解存在问题。
于是我下面又做了一种尝试,将调用那里改成直接调用service实现类:

    @Autowired
    private UserDetailsServiceImpl userDetailsServiceImpl;

此时保留注解:@ComponentScan(“com.example.service”)。
这种情况程序正常启动,但是当我访问验证的时候,他还是报上面那个错误。

最后我再去掉注解@ComponentScan(“com.example.service”)。程序恢复正常。

到此,我的各种尝试结束,我现在把问题锁定在@ComponentScan和service层接口的配置这块,目前还没弄明白到底为什么,所以我的标题这么写,主要还是这个注解到底怎么回事。

在此也是希望有大佬能帮我解答一下。

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lsjweiyi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值