- description li>
- detailed error message li>
- error analysis li>
- why li>
- solution li> ul>
problem description
springboot+mybatis, write interface and implementation classes, and use @autowired injection controller, start exception: required a single bean, but 2 were found
controller interface:
@RestController
@RequestMapping("/api/sys/statistic")
public class StatisticController {
@Autowired
private ISysAccessLogService iSysAccessLogService;
}
interface and implementation class
detail error
APPLICATION FAILED TO START
Description:
Field iSysAccessLogService in com.msb.sys.controller.StatisticController required a single bean, but 2 were found:
– sysAccessLogServiceImpl: defined in file [/Users/ronghuilin/java/msbjava/target/classes/com/msb/sys/service/impl/SysAccessLogServiceImpl.class]
– ISysAccessLogService: defined in file [/Users/ronghuilin/java/msbjava/target/classes/com/msb/sys/service/ISysAccessLogService.class]
Action:
Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
Disconnected from the target VM, address: ‘127.0.0.1:61739’, transport: ‘socket’
error analysis
if you’re prompted, there’s no way to automatically inject iSysAccessLogService at StatisticController.
@autowired is injected by type by default, and as prompted, my project has two beans of this type, so it cannot be injected automatically.
The
error message also suggests a solution:
1. Use one of the beans with the @primary annotation as the default,
2. Add @qualifier to the injected property to specify beanName to specify which bean
to use
but I’ve only written one implementation class for the interface, and as expected there’s only one bean, which should be fine.
Reason
h2>
after a roundabout search, I found that I had annotated springboot’s boot class with @mapperscan (” “com”).
@mapperscan this is the annotation is the Mapper scan annotation for mybatis, and the scope of the scan I specified is the com package.
mybatis scans the interface under com, generates the implementation class of the interface, and infuses it into spring.
then spring scans the interface implementation class I wrote, injects spring, and you have two beans.
solution
in the springboot project it is recommended to add @mapper directly to the Mapper interface and not to use @mapperscan.
if you want to use @mapperscan annotations, be careful to configure the scope of the scan to avoid the above problems caused by repeat scan injection of spring beans.