最近学习不同的项目用的不同的自动装配注解,所以记录了一下区别,当做以后的复习。
大部分来源一些博文,自己整理一下。
@Resource和@Autowired都是做bean的注入时使用,大部分使用时作用是一样的。
不过@Resource与@Autowired的导入的包不同。
一.相同的是
二者都可以用在字段和属性方法上,用在字段上可以不用写setter的方法。
下面我以@Autowired举例:
二.不同的是
- @Resource 导入包 (import javax.annotation.Resource;)是J2EE的注解
- @Autowired 导入包 ( import org.springframework.beans.factory.annotation.Autowired;)是spring的注解
- //在这一点上我比较偏向于@Resource,因为这个注解是属于J2EE的,减少了与spring的耦合。
@Autowired注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。如:@Autowired(required=false)
如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用。
@Resource默认按照ByName自动注入,@Resource有两个重要的属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。
所以,如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不制定name也不制定type属性,这时将通过反射机制使用byName自动注入策略。
说这么多其实很迷,代码走一波。
接口:Product
public interface Product {
public void resource();
}
定义两个实例
实例一:Maven
public class Maven implements Product {
@Override
public void resource() {
System.out.println("吃饭");
}
}
实例二:Redis
public class Redis implements Product {
@Override
public void resource() {
System.out.println("睡觉");
}
}
Test类:ProductServiceImpl
public class ProductServiceImpl implements ProductService {
//起服务此处会报错
@Resource
private Product product;
}
- 严重: Exception sendingcontext initialized event to listener instance of classorg.springframework.web.context.ContextLoaderListenerorg.springframework.beans.factory.BeanCreationException: Error creating beanwith name 'testServiceImpl': Injection of resource dependencies failed;
- nested exception isorg.springframework.beans.factory.NoUniqueBeanDefinitionException: Noqualifying bean of type [Test.com.service.Product] is defined:expected single matching bean
- but found 2: maven,redis
报错的地方给我们提示了:but found 2: maven,redis 意思是Product有两个实现类。解决方案如下:
public class ProductServiceImpl implements ProductService {
@Resource(name = "maven")//注意是manImpl不是ManImpl,因为使用@Service,容器为我们创建bean时默认类名首字母小写
private Product product;
}
这样启动服务就不会报错了。如果是使用的@Autowired注解,要配上@Qualifier("maven"),代码如下:
public class ProductServiceImpl implements ProductService {
@Autowired
@Qualifier("maven")
private Product product;
}
其次再说一下@Resource
@Resource装配顺序
1. 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
2. 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
3. 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
4. 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;
其他一些详细地址:
https://blog.csdn.net/wangzuojia001/article/details/54312074
https://www.cnblogs.com/leiOOlei/p/3713779.html
https://blog.csdn.net/weixin_40423597/article/details/80643990