Spring注解 @Resource 和 @Autowired 区别对比
@Resource 和 @Autowired 都是做bean的注入时使用,其实@Resource并不是Spring的注解,它的包是javax.annotation.Resource,需要导入,但是Spring支持该注解的注入。
1、共同点
@Resource 和 @Autowired 两者都可以写在字段 和 setter 方法上。
@Resource 和 @Autowired 两者如果都写在字段上,那么就不需要再写setter方法。
2、不同点
1) @Autowired
@Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired;只按照byType注入。
public class TestServiceImpl { // 下面两种@Autowired只要使用一种即可 @Autowired private UserDao userDao; // 用于字段上 @Autowired public void setUserDao(UserDao userDao) { // 用于属性的方法上 this.userDao = userDao; } }
@Autowired注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false,如:@Autowired(required=false)。如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用 。如下:
public class TestServiceImpl { @Autowired @Qualifier("userDao") private UserDao userDao; }
2)@Resource
@Resource默认按照 ByName自动注入,由J2EE提供,需要导入包 javax.annotation.Resource
@Resource有两个重要的属性:name 和 type
而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以,如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不制定name也不制定type属性,这时将通过反射机制使用byName自动注入策略。
public class TestServiceImpl { // 下面两种@Resource只要使用一种即可 @Resource(name="userDao") private UserDao userDao; // 用于字段上 @Resource(name="userDao") public void setUserDao(UserDao userDao) { // 用于属性的setter方法上 this.userDao = userDao; } }
注:最好是将@Resource放在setter方法上,因为这样更符合面向对象的思想,通过set、get去操作属性,而不是直接去操作属性。
@Resource装配顺序:
① 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。
② 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常。
③ 如果指定了type,则从上下文中找到类似匹配的唯一bean进行装配,找不到或是找到多个,都会抛出异常。
④如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配。
@Resource的作用相当于@Autowired,只不过@Autowired按照byType自动注入。
@Autowired 使用
首先要知道另一个东西,default-autowire,它是在xml文件中进行配置的,可以设置为byName、byType、constructor、autodetect
比如byName,不用显式的在bean中写出依赖的对象,它会自动的匹配其它bean中id名与本bean的set**相同的,并自动装载。
@Autowired是用在JavaBean中的注解,通过byType形式,用来给指定的字段或方法注入所需的外部资源。
两者的功能是一样的,就是能减少或者消除属性或构造器参数的设置,只是配置地方不一样而已。
@Autowired 四种模式的区别:
先看一下bean实例化和@Autowired装配过程:
一切都是从bean工厂的getBean方法开始的,一旦该方法调用总会返回一个bean实例,无论当前是否存在,不存在就实例化一个并装配,否则直接返回。(Spring MVC是在什么时候开始执行bean的实例化过程的呢?很简单就在组件扫描完成之后)
实例化和装配过程中会多次递归调用getBean方法来解决类之间的依赖。
Spring几乎考虑了所有可能性,所以方法特别复杂但完整有条理。
@Autowired最终是根据类型(byType)来查找和装配元素的,但是我们设置了<beans default-autowire="byName"/>
后会影响最终的类型匹配查找。因为在前面有根据BeanDefinition的autowire类型设置PropertyValue值得一步,其中会有新实例的创建和注册。就是那个autowireByName方法。
下面通过@Autowired来说明一下用法
Setter 方法中的 @Autowired
你可以在 JavaBean中的 setter 方法中使用 @Autowired 注解。
当 Spring遇到一个在 setter 方法中使用的 @Autowired 注解,它会在方法中执行 byType 自动装配。
这里是 TextEditor.Java 文件的内容:
package com.tutorialspoint; import org.springframework.beans.factory.annotation.Autowired; public class TextEditor { private SpellChecker spellChecker; @Autowired public void setSpellChecker( SpellChecker spellChecker ){ this.spellChecker = spellChecker; } public SpellChecker getSpellChecker( ) { return spellChecker; } public void spellCheck() { spellChecker.checkSpelling(); } }
下面是另一个依赖的类文件 SpellChecker.java 的内容:
package com.tutorialspoint; public class SpellChecker { public SpellChecker(){ System.out.println("Inside SpellChecker constructor." ); } public void checkSpelling(){ System.out.println("Inside checkSpelling." ); } }
下面是 MainApp.java 文件的内容:
package com.tutorialspoint; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); TextEditor te = (TextEditor) context.getBean("textEditor"); te.spellCheck(); } }
下面是配置文件 Beans.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:annotation-config/> <!-- Definition for textEditor bean without constructor-arg --> <bean id="textEditor" class="com.tutorialspoint.TextEditor"> </bean> <!-- Definition for spellChecker bean --> <bean id="spellChecker" class="com.tutorialspoint.SpellChecker"> </bean> </beans>
一旦你已经完成的创建了源文件和 bean 配置文件,让我们运行一下应用程序。
如果你的应用程序一切都正常的话,这将会输出以下消息:
Inside SpellChecker constructor.
Inside checkSpelling.
属性中的 @Autowired
你可以在属性中使用 @Autowired 注解来除去 setter 方法。
当时使用为自动连接属性传递的时候,Spring 会将这些传递过来的值或者引用自动分配给那些属性。所以利用在属性中 @Autowired 的用法,你的 TextEditor.java 文件将变成如下所示:
package com.tutorialspoint; import org.springframework.beans.factory.annotation.Autowired; public class TextEditor { @Autowired private SpellChecker spellChecker; public TextEditor() { System.out.println("Inside TextEditor constructor." ); } public SpellChecker getSpellChecker( ){ return spellChecker; } public void spellCheck(){ spellChecker.checkSpelling(); } }
下面是配置文件 Beans.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:annotation-config/> <!-- Definition for textEditor bean --> <bean id="textEditor" class="com.tutorialspoint.TextEditor"> </bean> <!-- Definition for spellChecker bean --> <bean id="spellChecker" class="com.tutorialspoint.SpellChecker"> </bean> </beans>
一旦你在源文件和 bean 配置文件中完成了上面两处改变,让我们运行一下应用程序。
如果你的应用程序一切都正常的话,这将会输出以下消息:
Inside TextEditor constructor.
Inside SpellChecker constructor.
Inside checkSpelling.
构造函数中的 @Autowired
你也可以在构造函数中使用 @Autowired。一个构造函数 @Autowired 说明当创建 bean 时,即使在 XML 文件中没有使用元素配置 bean ,构造函数也会被自动连接。让我们检查一下下面的示例。
这里是 TextEditor.java 文件的内容:
package com.tutorialspoint; import org.springframework.beans.factory.annotation.Autowired; public class TextEditor { private SpellChecker spellChecker; @Autowired public TextEditor(SpellChecker spellChecker){ System.out.println("Inside TextEditor constructor." ); this.spellChecker = spellChecker; } public void spellCheck(){ spellChecker.checkSpelling(); } }
下面是配置文件 Beans.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:annotation-config/> <!-- Definition for textEditor bean without constructor-arg --> <bean id="textEditor" class="com.tutorialspoint.TextEditor"> </bean> <!-- Definition for spellChecker bean --> <bean id="spellChecker" class="com.tutorialspoint.SpellChecker"> </bean> </beans>
一旦你在源文件和 bean 配置文件中完成了上面两处改变,让我们运行一下应用程序。
如果你的应用程序一切都正常的话,这将会输出以下消息:
Inside TextEditor constructor.
Inside SpellChecker constructor.
Inside checkSpelling.
@Autowired 的(required=false)选项
默认情况下,@Autowired 注解意味着依赖是必须的,它类似于 @Required 注解,
然而,你可以使用 @Autowired 的 (required=false) 选项关闭默认行为。
即使你不为 age 属性传递任何参数,下面的示例也会成功运行,但是对于 name 属性则需要一个参数。
你可以自己尝试一下这个示例,因为除了只有 Student.java 文件被修改以外,它和 @Required 注解示例是相似的。
package com.tutorialspoint; import org.springframework.beans.factory.annotation.Autowired; public class Student { private Integer age; private String name; @Autowired(required=false) public void setAge(Integer age) { this.age = age; } public Integer getAge() { return age; } @Autowired public void setName(String name) { this.name = name; } public String getName() { return name; } }
参考推荐:
Mybatis-Generator自动生成Dao、Model、Mapping
Spring注解@Resource和@Autowired区别对比
Spring 具体分析 applicationContext.xml 和 spring3-servlet.xml
Maven 搭建 SpringMVC+Spring+MyBatis 框架实战
Maven 构建 Spring MVC + MySQL + Mybatis 详细完整示例
Spring MVC:servlet 的url-pattern 匹配规则
Spring MVC @RequestParam @RequestBody @RequestHeader 详解
Spring 注解关键字解析 @Component、@Repository、@Service、@Controller @Resource、@Autowired、@Qualifier
版权所有: 本文系米扑博客原创、转载、摘录,或修订后发表,最后更新于 2021-01-17 20:11:19
侵权处理: 本个人博客,不盈利,若侵犯了您的作品权,请联系博主删除,莫恶意,索钱财,感谢!