Autowired使用说明
使用了那么久Spring,一下子问我Autowired注解使用条件,答不上来吧,看了Spring源码,一点点收货;
废话少说,要是Autowired生效,需要注册BeanPostProcessor,你说我没注册也能用啊,那你一定用了<context:annotation-config>或者<context:component-scan base-package="扫描包名/>这两个注解吧;
简单的测试代码(两个类 Person 以及 Pet ,一个Person类持有一个Pet类的关系)
Person类:
package com.lvbinbin.autowired;
import org.springframework.beans.factory.annotation.Autowired;
public class Person {
private String name; @Autowired
private Pet pet; public String toString() {
return "Person name:" + name + ",Pet:" + pet;
} public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Pet类:
package com.lvbinbin.autowired;
public class Pet {
private String name; public String toString() {
return "Pet name:"+name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Spring的配置文件(将Person以及Pet放到Spring容器里,或者通过包扫描加入容器)
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd"> <bean id="person1" class="com.lvbinbin.autowired.Person">
<property name="name" value="lvbinbin"></property>
</bean> <bean id="pet1" class="com.lvbinbin.autowired.Pet">
<property name="name" value="xiaobinggan"/>
</bean>
</beans>
简单写个类测试一下:
 package com.lvbinbin.autowired;
 import org.springframework.context.support.ClassPathXmlApplicationContext;
 public class TestCases {
     public static void main(String[] args) {
         ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("com/lvbinbin/autowired/spring.xml");
         Person p1=(Person) context.getBean("person1");
         System.out.println(p1);
     }
 }
以上代码,测试发现没有注入Pet属性; 也说明了 XML文件 property注入属性需要有对应的Setter Getter方法;
在Spring配置文件中加入下面几句话之一,Autowired就可以生效: <bean id="aabp" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
或者 <context:annotation-config/>
或者 <context:component-scan base-package="包路径"/>
其中包路径随意写也能使用Autowired注解生效,但是不建议写无意义的路径;
额外注意几点: 1. Autowired注解只有一个属性 required 可选值 false / true : 默认为true ,如果实例化该属性时候,IOC容器即BeanFactory中没有可以注入的,抛出异常 ;
设置为false ,实例化该属性时候 容器里没有该类型的bean 同样可以运行 ;
2.Autowired注解的属性可以有setter getter方法;底层是通过反射设置上的值,setter getter方法需不需要都可以成功 ;
3.Autowired注解可以标注在属性、或者方法上, 但是属性和方法都不允许为 static 类型;
4.Autowired注解可以注入一些Spring默认配置上的,ApplicationContext、BeanFactory、Enviroment等等对象;
5.Autowired注解标注在方法上时,方法入参需要都在SpringIOC容器中存在,该类型对象有一个不存在就会抛出异常
偷懒给Person类添加一些public属性;

测试main方法如下:
 public static void main(String[] args) {
         ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("com/lvbinbin/autowired/spring.xml");
         Person p1=(Person) context.getBean("person1");
         System.out.println(p1);
         System.out.println("ac:"+p1.ac);
         System.out.println("bf:"+p1.bf);
         System.out.println("rl:"+p1.rl);
         System.out.println("ap:"+p1.ap);
         System.out.println("env:"+p1.env);
     }
查看下输出:其实ResourceLoader、ApplicationEventPublisher都是ApplicationContext的具体对象,因为ApplicationContext实现了这些接口;

博客的最后,记录一个笨比的尝试:(下面的例子是Spring源码编译后改动,编译教程建议看Spring源码深度解析)
Autowired注解可以标注在 方法入参上,测试一下:

上例Person类简单改造下:注释掉 Pet属性上的Autowired,在方法入参中加上@Autowired;这里补充下:Autowired的注解的方法名不一定非要set这种形式的方法;
// @Autowired
private Pet pet; public void test1(@Autowired Pet p) {
this.pet=p;
}
同样的测试用例:发现Pet属性并没有注入上去(如果可以注入上去望指教);

简单改造下,可以支持 单个参数的Autowired注入,多个参数的Autowired实现,我力有不逮;
AutowiredAnnotationBeanPostProcessor的 findAutowiredAnnotation方法简单改造下,如果入参是Method且没有注解标注,顺便检查下参数上是否有Autowired注解,没有再返回null,就可以简单实现单个参数上的Autowired功能吧
@Nullable
private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) {
if (ao.getAnnotations().length > 0) { // autowiring annotations have to be local
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ao, type);
if (attributes != null) {
return attributes;
}
}
}
return null;
}
改造添加几行代码后方法这样的:
@Nullable
private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) {
if (ao.getAnnotations().length > 0) { // autowiring annotations have to be local
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ao, type);
if (attributes != null) {
return attributes;
}
}
}
if(ao instanceof Method) {
Parameter[] parameters = ((Method) ao).getParameters();
for (Parameter parameter : parameters) {
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(parameter, type);
if (attributes != null) {
return attributes;
}
}
}
}
return null;
}
同样的我们再测试下:发现已经可以实现了Autowired单个属性的注入,多个属性的改造量太大,可以(wo)但(bu)没必要(hui);

Autowired使用说明的更多相关文章
- Spring依赖注入 --- 简单使用说明
		
Spring依赖注入 --- 简单使用说明 本文将对spring依赖注入的使用做简单的说明,enjoy your time! 1.使用Spring提供的依赖注入 对spring依赖注入的实现方法感兴趣 ...
 - DUBBO功能使用说明
		
DUBBO功能使用说明 1 DUBBO概述 DUBBO是阿里巴巴公司的一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案. 相比于其他服务框架,DUBBO有如 ...
 - spring注解源码分析--how does autowired works?
		
1. 背景 注解可以减少代码的开发量,spring提供了丰富的注解功能.我们可能会被问到,spring的注解到底是什么触发的呢?今天以spring最常使用的一个注解autowired来跟踪代码,进行d ...
 - Atitit.项目修改补丁打包工具 使用说明
		
Atitit.项目修改补丁打包工具 使用说明 1.1. 打包工具已经在群里面.打包工具.bat1 1.2. 使用方法:放在项目主目录下,执行即可1 1.3. 打包工具的原理以及要打包的项目列表1 1. ...
 - Spring5:@Autowired注解、@Resource注解和@Service注解
		
什么是注解 传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺点: 1.如果所有的内容都配置在.xml文件中,那么.xml文件将会十分庞大:如果按需求分 ...
 - awk使用说明
		
原文地址:http://www.cnblogs.com/verrion/p/awk_usage.html Awk使用说明 运维必须掌握的三剑客工具:grep(文件内容过滤器),sed(数据流处理器), ...
 - @Autowired注解的使用
		
使用Spring时,通过Spring注入的Bean一般都被定义成private,并且要有getter和setter方法,显得比较繁琐,增加了代码量,而且有时会搞忘造成错误. 可以使用@Autowire ...
 - Spring-test使用JUnit时,测试类autowired报错,create bean error
		
Spring-test使用JUnit时,测试类里面使用autowired会报错, 报create bean error...... 但是controller里面@autowired可以正常运行的. 在 ...
 - @Autowired
		
1. Spring框架中进行注入式,使用@Autowired. @Autowired可以对成员变量.方法和构造函数进行标注,来完成自动装配的工作,这里必须明确:@Autowired是根据类型进行自动装 ...
 
随机推荐
- CAP 理论
			
CAP理论被很多人拿来作为分布式系统设计的金律,然而感觉大家对CAP这三个属性的认识却存在不少误区.从CAP的证明中可以看出来,这个理论的成立是需要很明确的对C.A.P三个概念进行界定的前提下的.在本 ...
 - android根据图片路径显示图片
			
首先根据图片路径先创建一个文件path为图片路径:然后判断文件是否存在,如果存在,将图片显示出来. File file = new File(path); ImageView img = (Image ...
 - Oracle EBS登陆后,直接打开某个特定Form/Page
			
http://blog.csdn.net/pan_tian/article/details/8169339 有一个小技巧,Oracle EBS登陆后可以绕过职责和功能的选择过程,就可以直接打开某个特定 ...
 - WPF如何设置Image.Source为资源图片
			
img.Source = new BitmapImage(new Uri(path,UriKind.RelativeOrAbsolute));
 - 键'attachdbfilename'的值无效。
			
---恢复内容开始--- ---恢复内容结束---
 - 剑指offer编程题Java实现——面试题7相关题用两个队列实现一个栈
			
剑指offer面试题7相关题目:用两个队列实现一个栈 解题思路:根据栈的先入后出和队列的先入先出的特点1.在push的时候,把元素向非空的队列内添加2.在pop的时候,把不为空的队列中的size()- ...
 - 如何在Notepad ++中每两行合并
			
\n 新行 \r 行首 [^\n]+ 是排除\n外的任意字符 [^\r]+ 是排除\r外的任意字符 用[^\n]或[^\r]都不行..老是匹配到空的东西..原来是这么一回事..用[^\n\r]+就行了 ...
 - CSV Data Set Config设置
			
Jmeter参数化常用的两种方法: 1.使用函数助手 2.CSV Data Set Config 本章主要讲解CSV Data Set Config设置 1.Filename:文件名,指保存信息的文件 ...
 - [Leetcode]44.跳跃游戏Ⅰ&&45.跳跃游戏Ⅱ
			
跳跃游戏链接 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 判断你是否能够到达最后一个位置. 示例 1: 输入: [2,3,1,1,4] 输出 ...
 - c++之window.h
			
在c++中引入window.h头文件. Sleep函数,此函数接受一个时间参数,单位是ms.即使得程序在一段时间后继续运行.如下: 在hello输出之后3000ms,才会继续输出world字符串. M ...