You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring项目出现UnsatisfiedDependencyException异常及注解使用咨询

解答:Spring中接口与实现类的注解使用及代理类型错误修复

Great question! Let's break this down step by step, covering both your annotation question and the error you're seeing.

核心问题:能不能在DAO/Service接口和实现类上同时标注@Repository/@Service?

绝对不要在接口上标注@Repository、@Service这类 stereotype 注解。原因很简单:

  • 这些注解的作用是告诉Spring:“这个类是一个需要被你管理的Bean,请为它创建实例”。但接口本身无法被实例化,Spring根本没法创建接口的Bean对象。
  • 在接口上加这些注解不仅完全没用,还会干扰Spring的Bean扫描逻辑,甚至间接导致你现在遇到的类型不匹配错误。

你应该只在具体的实现类上标注这些注解:比如UserDaoImpl上的@Repository、UserServiceImpl上的@Service是正确的,但UserDao接口上的@Repository、UserService接口上的@Service必须删掉。

为什么会出现BeanNotOfRequiredTypeException错误?

Let's look at your error message again:

Bean named 'userDaoImpl' is expected to be of type 'com.project.shopping.dao.impl.UserDaoImpl' but was actually of type 'com.sun.proxy.$Proxy56'

Here's the root cause:

  1. 你给UserDaoImpl加了@Transactional注解,Spring会为这个类创建JDK动态代理(因为它实现了UserDao接口)。JDK动态代理的本质是生成一个实现了目标接口的代理类,而不是继承目标类的子类。
  2. 但你在UserServiceImpl里注入的是UserDaoImpl(具体类类型),而Spring实际创建的代理对象是UserDao接口类型的。这就导致了类型不匹配——你试图把一个接口类型的代理对象塞进一个具体类类型的字段里,Spring自然会报错。

同样的问题也出现在你的UserController里,你注入的是UserServiceImpl具体类,而不是UserService接口。

修复步骤

1. 移除接口上的多余注解

修改UserDao.java,删掉@Repository:

// 去掉@Repository注解
public interface UserDao {
    public List<User> getAllUser();
}

修改UserService.java,删掉@Service:

// 去掉@Service注解
public interface UserService {
    public List<User> listUser();
}

2. 改为注入接口类型而非具体实现类

修改UserServiceImpl.java,把注入的类型改成UserDao接口:

@Service
public class UserServiceImpl implements UserService {
    // 改为注入UserDao接口,而非UserDaoImpl具体类
    @Autowired
    private UserDao userDao;

    public List<User> listUser() {
        return userDao.getAllUser();
    }
}

修改UserController.java,把注入的类型改成UserService接口:

@Controller
@RequestMapping("/")
public class UserController {
    // 改为注入UserService接口,而非UserServiceImpl具体类
    @Autowired
    UserService userService;

    @RequestMapping(method = RequestMethod.GET,value = "/allusers" , produces = "application/json")
    @ResponseBody
    public List<User> sayHello(ModelMap model) {
        return userService.listUser();
    }
}

3. 额外检查:确保事务配置正确

虽然这不是当前错误的直接原因,但要确保你的Spring配置中已经正确配置了事务管理器,比如:

@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = "com.project.shopping")
public class AppConfig {
    // 配置SessionFactory和TransactionManager的代码...
}

总结一下

  • 只在具体实现类上标注@Repository、@Service、@Controller等注解,接口不需要这些注解。
  • 依赖注入时始终依赖接口类型,而不是具体实现类——这不仅符合面向对象的依赖倒置原则,还能完美适配Spring的动态代理机制,避免类型不匹配的问题。

内容的提问来源于stack exchange,提问作者Bishwa Karki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:15:12