背景
今天在写一个数据处理程序的时候, 我打算优化一下我的程序, 本来是直接用Mapper层进行单行记录保存的, 也就是调用的Mapper的insert函数
过程
然后我就写了一个Service, 但是我没有写接口, 是直接写了一个具体的实现类
代码语言:javascript复制@Service
public class InstitutionService extends ServiceImpl<InstitutionMapper, Institution>{
}
这样看应该是没问题的吧
使用方式
代码语言:javascript复制@Autowired
protected InstitutionService institutionService;
直接在其他类中注入使用, 我打算直接用它的saveBatch函数
问题
然后就出现了标题中的一幕, 启动项目报错了
代码语言:javascript复制2023-01-09 10:45:22,854 WARN (AbstractApplicationContext.java:559)- Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'indexController': Unsatisfied dependency expressed through field 'organService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'organService': Unsatisfied dependency expressed through field 'institutionService'; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'institutionService' is expected to be of type 'com.example.parsedata.service.InstitutionService' but was actually of type 'com.sun.proxy.$Proxy74'
2023-01-09 10:45:22,855 INFO (DruidDataSource.java:2003)- {dataSource-1} closing ...
2023-01-09 10:45:22,858 INFO (DruidDataSource.java:2075)- {dataSource-1} closed
2023-01-09 10:45:22,860 INFO (DirectJDKLog.java:173)- Stopping service [Tomcat]
2023-01-09 10:45:22,869 INFO (ConditionEvaluationReportLoggingListener.java:136)-
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2023-01-09 10:45:22,871 ERROR (LoggingFailureAnalysisReporter.java:40)-
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'institutionService' could not be injected as a 'com.example.parsedata.service.InstitutionService' because it is a JDK dynamic proxy that implements:
Action:
Consider injecting the bean as one of its interfaces or forcing the use of CGLib-based proxies by setting proxyTargetClass=true on @EnableAsync and/or @EnableCaching.
分析
这里就可以分析一下问题原因了, 其实Description和Action描述的已经很清楚了
Description
这个Bean institutionService 在进行自动装配的时候不能找到 InstitutionService这个类, 因为使用的是JDK动态代理实现的
Action
考虑作为一个接口的实现, 或者强制使用CGLIB动态代理
应为Spring默认使用的是JDK的动态代理, 而JDK动态代理是基于接口实现的, 而在生成了代理类之后, 因为注入的不是接口, 而是实现类, 所以无法注入
解决
创建一个接口给现在的类实现
代码语言:javascript复制public interface IInstitutionService extends IService<Institution> {
}
代码语言:javascript复制@Service
public class InstitutionService extends ServiceImpl<InstitutionMapper, Institution> implements IInstitutionService{
}
使用时注入接口
代码语言:javascript复制@Autowired
protected IInstitutionService institutionService;
再次启动, 就OK了, 完美解决