zoukankan      html  css  js  c++  java
  • 从一个异常探索spring autowired 的原理

    从一个异常探索autowired 的原理。

    首先环境是这样的:

    public class Boss {
    
    
        @Autowired
        private Car car;
    
    }
    
    //@Component 加上这个注释,上面的Boss 的Autowired car就会失败,出现下面的异常
    public class Car {
        private String brand;
        private double price;
    
    }

    xml 是这样的:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
           xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
                    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
                    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
            >
            
    
        <context:component-scan base-package="com.baobaotao"></context:component-scan>
    
        <!-- 该 BeanPostProcessor 将自动起作用,对标注 @Autowired 的 Bean 进行自动注入 -->
        <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
    
        <!-- 移除 boss Bean 的属性注入配置的信息 -->
        <bean id="boss" class="com.baobaotao.Boss"/>
     <!--
        <bean id="office" class="com.baobaotao.Office">
            <property name="officeNo" value="001"/>
        </bean>
        <bean id="car" class="com.baobaotao.Car" scope="singleton">
            <property name="brand" value=" 红旗 CA72"/>
            <property name="price" value="2000"/>
        </bean>-->
        
    </beans>

    测试类:

    import com.baobaotao.Boss;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = {"classpath:/beans.xml"})
    public class AutowiredlTest extends
            AbstractJUnit4SpringContextTests {
    
        @Autowired
        Boss boss;
    
        @Test
        public void aaa() {
            System.out.println("boss = " + boss);
    
        }
    }

    结果是出现异常:

    D:softjavajdk1.7injava -Didea.launcher.port=7533 "-Didea.launcher.bin.path=D:Program Files (x86)JetBrainsIntelliJ IDEA Community Edition 2016.1.2in" -Dfile.encoding=UTF-8 -classpath "D:softjavajdk1.7jrelibcharsets.jar;D:softjavajdk1.7jrelibdeploy.jar;D:softjavajdk1.7jrelibextaccess-bridge-64.jar;D:softjavajdk1.7jrelibextdnsns.jar;D:softjavajdk1.7jrelibextjaccess.jar;D:softjavajdk1.7jrelibextlocaledata.jar;D:softjavajdk1.7jrelibextsunec.jar;D:softjavajdk1.7jrelibextsunjce_provider.jar;D:softjavajdk1.7jrelibextsunmscapi.jar;D:softjavajdk1.7jrelibextzipfs.jar;D:softjavajdk1.7jrelibjavaws.jar;D:softjavajdk1.7jrelibjce.jar;D:softjavajdk1.7jrelibjfr.jar;D:softjavajdk1.7jrelibjfxrt.jar;D:softjavajdk1.7jrelibjsse.jar;D:softjavajdk1.7jrelibmanagement-agent.jar;D:softjavajdk1.7jrelibplugin.jar;D:softjavajdk1.7jrelib
    esources.jar;D:softjavajdk1.7jrelib
    t.jar;D:codewsspringhzspring-learn	arget	est-classes;D:codewsspringhzspring-learn	argetclasses;C:Userslkms.m2
    epositoryjunitjunit4.12junit-4.12.jar;C:Userslkms.m2
    epositoryorghamcresthamcrest-core1.3hamcrest-core-1.3.jar;C:Userslkms.m2
    epositoryorgspringframeworkspring-context4.3.5.RELEASEspring-context-4.3.5.RELEASE.jar;C:Userslkms.m2
    epositoryorgspringframeworkspring-aop4.3.5.RELEASEspring-aop-4.3.5.RELEASE.jar;C:Userslkms.m2
    epositoryorgspringframeworkspring-beans4.3.5.RELEASEspring-beans-4.3.5.RELEASE.jar;C:Userslkms.m2
    epositoryorgspringframeworkspring-core4.3.5.RELEASEspring-core-4.3.5.RELEASE.jar;C:Userslkms.m2
    epositorycommons-loggingcommons-logging1.2commons-logging-1.2.jar;C:Userslkms.m2
    epositoryorgspringframeworkspring-expression4.3.5.RELEASEspring-expression-4.3.5.RELEASE.jar;C:Userslkms.m2
    epositoryorgspringframeworkspring-web4.3.5.RELEASEspring-web-4.3.5.RELEASE.jar;C:Userslkms.m2
    epositoryorgspringframeworkspring-test4.3.5.RELEASEspring-test-4.3.5.RELEASE.jar;D:Program Files (x86)JetBrainsIntelliJ IDEA Community Edition 2016.1.2libidea_rt.jar" com.intellij.rt.execution.application.AppMain AnnoIoCTest
    十一月 11, 2017 2:21:34 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
    INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@7a277bd2: startup date [Sat Nov 11 14:21:34 CST 2017]; root of context hierarchy
    十一月 11, 2017 2:21:34 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
    INFO: Loading XML bean definitions from class path resource [beans.xml]
    十一月 11, 2017 2:21:35 下午 org.springframework.context.support.ClassPathXmlApplicationContext refresh
    WARNING: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'boss': Unsatisfied dependency expressed through field 'car'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.baobaotao.Car' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'boss': Unsatisfied dependency expressed through field 'car'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.baobaotao.Car' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
        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:1225)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:552)
        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:759)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
        at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
        at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
        at AnnoIoCTest.main(AnnoIoCTest.java:8)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)
        at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
    Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.baobaotao.Car' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1474)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1102)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1064)
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
        ... 20 more
    
    Process finished with exit code 1

    spring 的启动过程中会读取配置的xml,注册所有的 beanDefinition,这个是准备过程。 准备完后是 beanfactory 的refresh ,这个时候会 进行注解的处理, 也就是 BeanPostProcessor。 这其中就包含了对 bean 中包含的各种注解的 解析, 比如 Autowired 注解等。 AutowiredAnnotationBeanPostProcessor 的 postProcessPropertyValues 是继承于InstantiationAwareBeanPostProcessor  。 是对它的实现。 如果我们仔细观察这个错误堆栈, 也许我们会从中发现很多很多的细节。

    参考:

    http://blog.csdn.net/mack415858775/article/details/47721909 写得非常详细,非常好!

  • 相关阅读:
    如何实现1080P延迟低于500ms的实时超清直播传输技术
    直播体验深度优化方案——连麦互动直播
    前向纠错码(FEC)的RTP荷载格式
    C++通过COM接口操作PPT
    neo4j的搭建和实例使用
    【neo4j】neo4j Desktop1.1.9,windows 安装
    Neo4j删除节点和关系、彻底删除节点标签名
    知识图谱赵军学习笔记(五)--实体消歧
    实体消歧简介
    svn服务器时间与本地时间不同步解决
  • 原文地址:https://www.cnblogs.com/FlyAway2013/p/7819091.html
Copyright © 2011-2022 走看看