从一个异常探索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=""/>
</bean>
<bean id="car" class="com.baobaotao.Car" scope="singleton">
<property name="brand" value=" 红旗 CA72"/>
<property name="price" value=""/>
</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:\soft\java\jdk1.\bin\java -Didea.launcher.port= "-Didea.launcher.bin.path=D:\Program Files (x86)\JetBrains\IntelliJ IDEA Community Edition 2016.1.2\bin" -Dfile.encoding=UTF- -classpath "D:\soft\java\jdk1.7\jre\lib\charsets.jar;D:\soft\java\jdk1.7\jre\lib\deploy.jar;D:\soft\java\jdk1.7\jre\lib\ext\access-bridge-64.jar;D:\soft\java\jdk1.7\jre\lib\ext\dnsns.jar;D:\soft\java\jdk1.7\jre\lib\ext\jaccess.jar;D:\soft\java\jdk1.7\jre\lib\ext\localedata.jar;D:\soft\java\jdk1.7\jre\lib\ext\sunec.jar;D:\soft\java\jdk1.7\jre\lib\ext\sunjce_provider.jar;D:\soft\java\jdk1.7\jre\lib\ext\sunmscapi.jar;D:\soft\java\jdk1.7\jre\lib\ext\zipfs.jar;D:\soft\java\jdk1.7\jre\lib\javaws.jar;D:\soft\java\jdk1.7\jre\lib\jce.jar;D:\soft\java\jdk1.7\jre\lib\jfr.jar;D:\soft\java\jdk1.7\jre\lib\jfxrt.jar;D:\soft\java\jdk1.7\jre\lib\jsse.jar;D:\soft\java\jdk1.7\jre\lib\management-agent.jar;D:\soft\java\jdk1.7\jre\lib\plugin.jar;D:\soft\java\jdk1.7\jre\lib\resources.jar;D:\soft\java\jdk1.7\jre\lib\rt.jar;D:\code\ws\spring\hz\spring-learn\target\test-classes;D:\code\ws\spring\hz\spring-learn\target\classes;C:\Users\lkms\.m2\repository\junit\junit\4.12\junit-4.12.jar;C:\Users\lkms\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;C:\Users\lkms\.m2\repository\org\springframework\spring-context\4.3.5.RELEASE\spring-context-4.3.5.RELEASE.jar;C:\Users\lkms\.m2\repository\org\springframework\spring-aop\4.3.5.RELEASE\spring-aop-4.3.5.RELEASE.jar;C:\Users\lkms\.m2\repository\org\springframework\spring-beans\4.3.5.RELEASE\spring-beans-4.3.5.RELEASE.jar;C:\Users\lkms\.m2\repository\org\springframework\spring-core\4.3.5.RELEASE\spring-core-4.3.5.RELEASE.jar;C:\Users\lkms\.m2\repository\commons-logging\commons-logging\1.2\commons-logging-1.2.jar;C:\Users\lkms\.m2\repository\org\springframework\spring-expression\4.3.5.RELEASE\spring-expression-4.3.5.RELEASE.jar;C:\Users\lkms\.m2\repository\org\springframework\spring-web\4.3.5.RELEASE\spring-web-4.3.5.RELEASE.jar;C:\Users\lkms\.m2\repository\org\springframework\spring-test\4.3.5.RELEASE\spring-test-4.3.5.RELEASE.jar;D:\Program Files (x86)\JetBrains\IntelliJ IDEA Community Edition 2016.1.2\lib\idea_rt.jar" com.intellij.rt.execution.application.AppMain AnnoIoCTest
十一月 , :: 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@7a277bd2: startup date [Sat Nov :: CST ]; root of context hierarchy
十一月 , :: 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [beans.xml]
十一月 , :: 下午 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 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 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:)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:)
at org.springframework.beans.factory.support.AbstractBeanFactory$.getObject(AbstractBeanFactory.java:)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:)
at AnnoIoCTest.main(AnnoIoCTest.java:)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:)
at java.lang.reflect.Method.invoke(Method.java:)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.baobaotao.Car' available: expected at least 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:)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:)
... more Process finished with exit code
spring 的启动过程中会读取配置的xml,注册所有的 beanDefinition,这个是准备过程。 准备完后是 beanfactory 的refresh ,这个时候会 进行注解的处理, 也就是 BeanPostProcessor。 这其中就包含了对 bean 中包含的各种注解的 解析, 比如 Autowired 注解等。 AutowiredAnnotationBeanPostProcessor 的 postProcessPropertyValues 是继承于InstantiationAwareBeanPostProcessor 。 是对它的实现。 如果我们仔细观察这个错误堆栈, 也许我们会从中发现很多很多的细节。
参考:
http://blog.csdn.net/mack415858775/article/details/47721909 写得非常详细,非常好!
从一个异常探索spring autowired 的原理的更多相关文章
- Spring异步调用原理及SpringAop拦截器链原理
一.Spring异步调用底层原理 开启异步调用只需一个注解@EnableAsync @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTI ...
- Spring Security 入门原理及实战
目录 从一个Spring Security的例子开始 创建不受保护的应用 加入spring security 保护应用 关闭security.basic ,使用form表单页面登录 角色-资源 访问控 ...
- Spring Boot启动原理解析
Spring Boot启动原理解析http://www.cnblogs.com/moonandstar08/p/6550758.html 前言 前面几章我们见识了SpringBoot为我们做的自动配置 ...
- spring boot 启动原理详细解析
我们开发任何一个Spring Boot项目,都会用到如下的启动类 1 @SpringBootApplication 2 public class Application { 3 public stat ...
- [转帖]Spring Cloud底层原理
拜托!面试不要再问我Spring Cloud底层原理 https://mp.weixin.qq.com/s/ZH-3JK90mhnJPfdsYH2yDA 毫无疑问,Spring Cloud 是目前微服 ...
- struts1,struts2,hibernate,spring的运行原理结构图
一.struts1运行原理 1.初始化:struts框架的总控制器ActionServlet是一个Servlet,它在web.xml中配置成自动启动的Servlet,在启动时总控制器会读取配置文件(s ...
- 何为代理?jdk动态代理与cglib代理、spring Aop代理原理浅析
原创声明:本博客来源为本人原创作品,绝非他处摘取,转摘请联系博主 代理(proxy)的定义:为某对象提供代理服务,拥有操作代理对象的功能,在某些情况下,当客户不想或者不能直接引用另一个对象,而代理对象 ...
- 拜托!面试请不要再问我Spring Cloud底层原理[z]
[z]https://juejin.im/post/5be13b83f265da6116393fc7 拜托!面试请不要再问我Spring Cloud底层原理 欢迎关注微信公众号:石杉的架构笔记(id: ...
- spring Mvc 执行原理 及 xml注解配置说明 (六)
Spring MVC 执行原理 在 Spring Mvc 访问过程里,每个请求都首先经过 许多的过滤器,经 DispatcherServlet 处理; 一个Spring MVC工程里,可以配置多个的 ...
随机推荐
- Task Class
https://docs.microsoft.com/zh-cn/dotnet/api/system.threading.tasks.task?redirectedfrom=MSDN&view ...
- 我的less学习之路
less注释 可以在代码中使用块样式(/* */)和行内注释(//),但是当编译LESS代码时,单行注释不会显示在CSS文件中.开发中主要维护的是less文件,所以可以使用行内注释,最终编译的css文 ...
- a:hover应用精粹
原本想把题目叫做“纯CSS相册2”的,但在实现过程中试验了许多东西,干脆全部写出来分享了.大家知道,能兼容IE6的具有动态切换能力的CSS属性也只有hover伪类了,但hover伪类在IE仅对链接生效 ...
- 【Spring学习笔记-3】国际化支持
[Spring]国际化支持 一.总体结构: 两个国际化资源中的内容: 二.程序 2.1 配置Spring上下文 beans.xml文件 <?xml version="1.0" ...
- vue中滚动事件绑定的函数无法调用问题
问题描述: 一个包含下拉加载的页面,刷新当前页然后滚动页面,能够正常触发滚动事件并调用回调函数,但是如果是进了某一个页面然后再进的该页面,滚动事件能够触发, 但是回调函数在滚动的时候只能被调用一次. ...
- ubuntu16.04下sublime text 3之安装和配置
1.安装方法 1)使用ppa安装 sudo add-apt-repository ppa:webupd8team/sublime-text-3 sudo apt-get update sudo apt ...
- MyBatis的入门案例
1.MyBatis的结构 2.MyBatis入门案例 a.创建java项目,并在其中导入相关开发包 b.导入约束文件 http://mybatis.org/dtd/mybatis-3-config.d ...
- [转][CentOS]VI编辑器使用
参考:https://blog.csdn.net/qq_34160679/article/details/79800584 参考:https://www.cnblogs.com/mondol/p/vi ...
- 廖雪峰Java4反射与泛型-2注解-3处理注解
1.处理注解 注解本身对对代码逻辑没有任何影响 SOURCE类型的注解在编译期就被丢掉了 CLASS类型的注解仅保存在class文件中 RUNTIME类型的注解在运行期可以被读取 如何使用注解由工具决 ...
- asp.net mvc 5 单元测试小例子
using System.Collections.Generic; using System.Linq; using Microsoft.VisualStudio.TestTools.UnitTest ...