Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'dao' is exp

本文解析了Spring框架中使用注解实现依赖注入时遇到的问题,重点介绍了如何正确配置和服务层与数据访问层的交互,同时深入探讨了Java动态代理机制在Spring中的应用。

异常信息:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'service': Unsatisfied dependency expressed through field 'dao'; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'dao' is expected to be of type 'ifox.DAOImpl' but was actually of type 'com.sun.proxy.$Proxy14'

at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at ifox.TestDb.<init>(TestDb.java:20)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:217)
at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:266)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'dao' is expected to be of type 'ifox.DAOImpl' but was actually of type 'com.sun.proxy.$Proxy14'
at org.springframework.beans.factory.support.DefaultListableBeanFactory.checkBeanNotOfRequiredType(DefaultListableBeanFactory.java:1510)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1489)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 41 more



今天在看spring注解的时候遇到这个问题可以说弄的自己很难受,我先贴上我的部分错误源码
DAO接口
package ifox;

/**
 * Created by exphuhong on 17-8-14.
 */
public interface DAO
{
    public Db findDbById(int id);

    public void saveBook(Db db);
}

DAO实现类

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;

/**
 * Created by exphuhong on 17-8-14.
 */
@Repository("dao")
public class DAOImpl implements DAO{

    @Autowired
    private SessionFactory sessionFactory;

    //获取和当前线程绑定的Seesion
    private Session getSession()
    {
        return sessionFactory.getCurrentSession();
    }

    public Db findDbById(int id)
    {
        String hql = "from Db  WHERE id = ?";
        return (Db) getSession().createQuery(hql).setInteger(0, id).uniqueResult();
    }
    public void saveBook(Db db)
    {
        getSession().save(db);
    }
}

Service接口
package ifox;

/**
 * Created by exphuhong on 17-8-14.
 */
public interface Service {
        public Db findDbById(int id);
        public void saveBook(Db db);

}

Service实现类

package ifox;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;


/**
 * Created by exphuhong on 17-8-14.
 */
@org.springframework.stereotype.Service("service")
public class ServiceImpl implements Service {

    @Autowired
    @Qualifier("dao")
    private DAO dao;   //错误用法  private DAOImpl dao;  原理在最下面

    public Db findDbById(int id)
    {
        return dao.findDbById(id);
    }
    public void saveBook(Db db)
    {
        dao.saveBook(db);

    }
}



测试类
package ifox;

import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * Created by exphuhong on 17-8-14.
 */
public class TestDb {

    private ApplicationContext context=null;
    private Service service=null;

    {
        context= new ClassPathXmlApplicationContext("applicationContext.xml");
        service = (Service) context.getBean("service");
    }

    @Test
    public void test1() {
        System.out.println(context.getBean("dao"));
    }

    @Test
    public void test2()
    {
        Db db= (Db) service.findDbById(5);
        System.out.println(db);
    }

    @Test
    public void test3()
    {
        service.saveBook(new Db("张飞",21,"1"));
    }
}
解释:
读者首先需要去了解java的反射机制以及java动态代理。spring注解是实现java注解接口的。注解的实现和java的一样,都是通过反射。通过反射实现动态代理机制,动态代理需要java.lang.reflect.InvocationHandler接口和java.lang.reflect.Prox类的支持。Prox类是专门完成代理的操作类,可以通过此类为一个或多个接口动态生成实现类
所以这里在获取通过注解的注入的bean时(通过反射将该类(接口的实现类)对应的bean注入到IOC容器中)需要定义成接口类型了只有这样才叫动态代理





### 问题分析 在 Spring 应用中,出现 `NoSuchBeanDefinitionException` 异常通常表示容器无法找到指定名称或类型的 Bean。具体到当前问题,异常信息为: ``` Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'bus' available ``` 这意味着 Spring 容器在启动过程中尝试解析名为 `bus` 的 Bean 时失败,可能的原因包括: - **未正确声明名为 `bus` 的 Bean**:例如在 Apache CXF 配置中未定义 `<cxf:bus>` 标签,导致默认的 Bus 实例未被注册。 - **命名空间配置不完整或错误**:Spring XML 配置文件中缺少对 CXF 命名空间的引用,导致 `<cxf:bus>` 无法识别。 - **依赖缺失或版本冲突**:项目中缺少必要的 CXF 依赖,或者存在多个版本的冲突,导致容器无法加载相关类。 - **IDE 缓存问题**:有时即使配置正确,IDE 可能仍显示错误提示,实际运行时也可能抛出该异常。 --- ### 解决方案 #### 1. 确保 `bus` Bean 被正确定义 Apache CXF 提供了 `<cxf:bus>` 标签用于自动注册一个名为 `bus` 的 Bean。只要在配置文件中正确使用该标签,即可直接通过 `ref="bus"` 引用它: ```xml <cxf:bus> <cxf:features> <cxf:logging/> </cxf:features> </cxf:bus> ``` 此配置会注册一个名为 `bus` 的 Bean,确保其他组件可以引用它[^2]。 #### 2. 检查命名空间和 Schema 地址 确保 XML 文件头部包含正确的命名空间声明及对应的 schemaLocation,尤其是针对 CXF 的部分: ```xml xmlns:cxf="http://cxf.apache.org/core" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd" ``` 只有在命名空间和 schemaLocation 正确的情况下,CXF 的标签才能被正确解析并注册为 Bean。 #### 3. 添加必要的 Maven 依赖 如果项目中缺少 CXF 的核心依赖,即使配置正确,Spring 容器也无法加载 `bus` Bean。请确保在 `pom.xml` 中添加如下依赖: ```xml <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-core</artifactId> <version>3.6.2</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> <version>3.6.2</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>3.6.2</version> </dependency> ``` 这些依赖是使用 CXF 功能所必需的,缺少它们会导致运行时找不到 Bean[^2]。 #### 4. 清理 IDE 缓存并重新加载依赖 有时即使配置完全正确,IDE 可能仍然标红某些标签或报错。此时应尝试执行以下操作: - 在 Maven 项目中运行 `mvn clean install` 以确保所有依赖已正确下载。 - 重启 IDE 并清除缓存(例如,在 IntelliJ 中可通过 `File > Invalidate Caches / Restart` 实现)。 - 重新导入项目以确保 XML 配置文件被正确解析。 --- ### 示例完整配置 以下是一个完整的 Spring XML 配置示例,确保 `bus` Bean 被正确注册并可被引用: ```xml <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cxf="http://cxf.apache.org/core" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd"> <cxf:bus> <cxf:features> <cxf:logging/> </cxf:features> </cxf:bus> <bean id="helloWorldEndpoint" class="org.apache.cxf.jaxws.EndpointImpl"> <constructor-arg ref="bus"/> <constructor-arg ref="helloWorld"/> <property name="address" value="/HelloWorld"/> </bean> <bean id="helloWorld" class="com.example.HelloWorldImpl"/> </beans> ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值