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 写得非常详细,非常好!

  • 相关阅读:
    CentOS查看CPU信息、位数、多核信息
    Linux常用命令大全
    chmod命令详细用法
    tar命令的详细解释
    yum和rpm命令详解
    LeetCode 241. Different Ways to Add Parentheses
    LeetCode 139. Word Break
    LeetCode 201. Bitwise AND of Numbers Range
    LeetCode 486. Predict the Winner
    LeetCode 17. Letter Combinations of a Phone Number
  • 原文地址:https://www.cnblogs.com/FlyAway2013/p/7819091.html
Copyright © 2011-2022 走看看