要讲区别,当然首先要讲这两个注解是做什么的呢,有什么作用呢?
用途:
文字描述:可以对成员变量、方法和构造函数进行标注,来完成自动装配的工作。@Autowired
标注可以放在成员变量上,也可以放在成员变量的set方法上,也可以放在任意方法上表示,自动执行当前方法,如果方法有参数,会在IOC容器中自动寻找同类型参数为其传值。
看完蒙了???
下面以一个示例讲解这两个注解的作用:
现在项目中已经引入了Spring,其spring-context.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd">
</beans>
现在我们定义宝马类和奔驰类
public class BWM
{
private String name= "宝马";
private String color= "红色";
public String toString(){
return this.name + ":" + this.color;
}
}
public class Benz
{
private String name= "奔驰";
private String color= "银色";
public String toString(){
return this.name + ":" + this.color;
}
}
现在我们定义再定义一个人
public class People
{
private BWM bwm;
private Benz benz;
public void setBWM(BWM bwm){
this.bwm= bwm;
}
public void setBenz(Benz benz){
this.benz= benz;
}
public Tiger getBWM(){
return bwm;
}
public Monkey getBenz(){
return benz;
}
public String toString(){
return bwm + "\n" + benz;
}
}
此时如果将这三个类纳入Spring进行管理,那么在spring-context.xml文件中定义bean对象,如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<bean id="people" class="com.lucas.bean.People" >
<property name="bwm" ref="bwm" />
<property name="benz" ref="benz" />
</bean>
<bean id="bwm" class="com.lucas.bean.BWN" />
<bean id="benz" class="com.lucas.bean.Benz " />
</beans>
通过以上配置,通过Spring上下文
拿到People
对象,Spring
会将BWM
和Benz
对象自动注入到People
的属性,这是通过Spring
的xml
文件配置。那么如何通过注解将BWM
和Benz
对象注入到People
中呢?这是我们的@Resource
和@Autowired
的作用来了。先揭晓答案是如何使用的。 见如下代码:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<!--扫描指定包,如果发现有指定注解,那么该类将由Spring进行管理(用到注解就要配置需要扫描的包哦,不然注解不会生效)-->
<!--com.lucas.*的意思是扫描com.lucas的包以及子包-->
<context:component-scan base-package="com.lucas.*" />
<!--将三个对象给Spring管理,没有对People的属性进行注入,只是单纯的把People给Spring管理-->
<bean id="people" class="com.lucas.bean.People" >
<bean id="bwm" class="com.lucas.bean.BWN" />
<bean id="benz" class="com.lucas.bean.Benz " />
</beans>
public class People
{
//使用@AutoWired和@Resource注解都可以不用写set方法,因为Spring通过反射暴力对Filed进行赋值
//当然也可以标注在属性的setter方法上,也是可以注入的,如果标在属性上那么就是通过set赋值。
@AutoWired
private BWM bwm;
@Resource
private Benz benz;
public Tiger getBWM(){
return bwm;
}
public Monkey getBenz(){
return benz;
}
public String toString(){
return bwm + "\n" + benz;
}
}
看到这里,是不是了解了@Resource
和@Autowired
是做什么用的呢,是不是这两个注解简化了一系列代码呢?在我们的web开发中,这两个注解是非常常用的,现在给大家详细介绍这两个注解的使用以及列举作者已经踩到的坑。。。
满满的干货:
@Resource和@Autowired的不同点:
(1)基因不同: 首先其最大的不同在于她们的爸爸妈妈不同(@Autowired
是由org.springframework.beans.factory.annotation.Autowired
提供,换句话说就是由Spring提供;@Resource
是由javax.annotation.Resource
提供,即J2EE提供,需要JDK1.6及以上。)
(2)注入方式:@Autowired默认按照byType 注入,也提供byName;@Resource默认按byName自动注入,也提供按照byType 注入;
等等-什么是byType
,什么是byName
注入 ????
解释一波:顾名思义,byType是通过类型进行装配,byName是通过名称进行装配。
- 类型装配:根据要装配的变量类进行查找,如下面的
@AutoWired
private BWM bwm;
Spring会自动根据BWM类去IOC容器中寻找他的实现类或子类进行装配(如果出现两个实现类怎么办??别急,往下看,下面会讲)。
- 名称装配:根据之前在
Spring-context.xml
配置的id进行查找,如果用的@Service(“id名”)
注解配置的,如果name
没写,则默认name会定义成非全限定类名(首字母小写,如:类名为BWM
则name
会默认为bWM
),此时@Autowired
和@Resource
的默认名称就是定义的属性名
@AutoWired(默认的查找名称为bwm)
private BWM bwm;
@Resource(默认的查找名称为benz)
private Benz benz;
那么你肯定想到了,如果我@Service
或者xml的id中是我自己定义的id名,那我该如何配置呢?Spring已经想到了,看下面代码写法:
/*
* 比如你把BWM类的id定义成了bm,Benz类的id定义成了bc
*/
@AutoWired
@Qualifier("bm")
private BWM bwm;
@Resource(name="bc")
private Benz benz;
这就是按照名称装配了
总结:
@Autowired
按类型装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它required属性为false。如果查询的结果不止一个,那么@Autowired会根据名称来查找。如果我们想使用按名称装配,也可以结合@Qualifier注解一起使用。
@Resource
有两个中重要的属性:name和type。name属性指定byName,如果没有指定name属性,当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象,当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找依赖对象。需要注意的是,@Resource如果没有指定name属性,并且按照默认的名称仍然找不到依赖对象时, @Resource注解会回退到按类型装配。但一旦指定了name属性,就只能按名称装配了。
@Resource装配顺序
-
如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
-
如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
-
如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
-
如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;
最后推荐使用
@Resource
注解在字段上,这样就不用写setter方法了.并且这个注解是属于J2EE的,减少了与Spring的耦合,这样代码看起就比较优雅 。