Spring整理系列(10)——@Autowired自动装配、结合@Qualifier过滤及与JSR-250@Resource注解、JSR-330@Inject注解的区别、@Named使用
来源:互联网 发布:js实现图片转base64 编辑:程序博客网 时间:2024/06/09 13:44
写在前面:在Spring整理系列(02)——spring依赖注入,组装对象之间的依赖关系文中,第三部分简单介绍了使用@Autowired注解自动装配bean的情况,此处引用一下。
一、使用@Autowired注解,实现自动装配
在使用注解装配之前,首先要开启注解装配的方式,那就是在配置文件中加上下面这句话<context:annotation-config></context:annotation-config>
,也可以使用<context:component-scan>
标签(两者的区别在Spring整理系列(01)——spring概念简介、bean扫描与注册实现方式中有提到)。
使用@Autowired注解,可以用在属性、setter方法、constructor构造方法上,实现自动装配。
spring的xml配置文件:
<!-- 开启注解配置 --> <context:annotation-config></context:annotation-config> <!-- 注册bean --> <bean id="userDao" class="com.jsun.test.springDemo.ioc.User.UserDaoImpl"></bean> <!-- 注册bean --> <bean id="userService" class="com.jsun.test.springDemo.ioc.User.UserServiceImpl"></bean>
UserServiceImpl:
1、注解在setter方法上:
private UserDao userDao; //添加注解,匹配注入与参数类型有关,即byType,与参数名称、setter方法名称、成员变量属性名称无关 @Autowired public void setUserDao(UserDao userDao) { System.out.println("注解自动装配setUserDao注入"); this.userDao = userDao; }
2、constructor构造方法上:
private UserDao userDao; //添加注解,匹配注入与参数类型有关,即byType,与参数名称、成员变量属性名称无关 @Autowired public UserServiceImpl(UserDao userDao){ System.out.println("注解自动装配构造器UserServiceImpl注入"); this.userDao = userDao; }
3、声明的属性上:
//添加注解,先按照属性名称匹配注入,如果未找到则按照属性类型匹配注入,即byName-->byType @Autowired private UserDao userDao;
二、使用@Autowired抛出异常情况及与@Qualifier注解结合使用情况
抛出异常情况:
@Autowired使用的时候必须只有一个Bean适合装配,否则spring会抛出异常;
1、NoSuchBeanDefinitionException异常:如果在应用上下文当中找不到相应的bean去自动装配,那么spring也会抛出异常。
。。。Caused by: org.springframework.beans.factory.BeanCreationException: 。。。Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type。。。
要避免这种情况发生,而且需要装配的属性也不是必须要装配的话,可以使用@Autowired(required=false)注解:
//在注入bean的时候该属性不是必须的,即使找不到对应bean注入,也不会报异常 @Autowired(required=false) private UserDao userDao;
2、NoUniqueBeanDefinitionException异常:如果在同一个spring容器中出现了两个或多个都必须存在的bean,然而自动装配只需要装配期中一个,也会抛出异常。
父类接口:
public interface TestBeanInterface { public void sayHello();}
两个实现子类:
@Component("testBean1")public class TestBean1 implements TestBeanInterface{ public void sayHello(){ System.out.println("TestBean1 sayHello..."); }}@Component("testBean2")public class TestBean2 implements TestBeanInterface{ public void sayHello(){ System.out.println("TestBean2 sayHello..."); }}
测试类中:
//以接口父类声明的成员变量属性,在spring容器中有它两个子类的bean private TestBeanInterface testBean; //自动装配,按照参数类型匹配注入bean,此时spring容器中TestBeanInterface类型有两个bean @Autowired public void setTestBean(TestBeanInterface t){ this.testBean = t; }
执行测试的异常:
。。。Caused by: org.springframework.beans.factory.BeanCreationException:。。。Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException:。。。
这个时候@Autowired可以结合使用@Qualifier注解指定一个Bean来装配:
@Autowired public void setTestBean(@Qualifier("testBean2")TestBeanInterface t){ this.testBean = t; }
注:@Qualifier注解其实就是先按照bean的name过滤装配指定类型bean,把@Autowired放在成员变量属性上,也是先按照属性name查找,再按类型注入,所以把@Autowired放在成员变量属性上报NoUniqueBeanDefinitionException异常的概率比较低,并且不需要setter或构造器,推荐使用。
三、@Autowired可以装配的spring内部bean,不可以装配的bean
1、@Autowired可以注解的spring内部类型:
可以用@Autowired注解那些解析依赖性接口,比如BeanFactory、ApplicationContext、Environment、ResourceLoader、ApplicationEventPublisher、MessageSource等
@Autowired private ApplicationContext context; @Test public void testGetBean(){ TestBeanInterface tb = (TestBeanInterface)context.getBean("testBean1"); System.out.println(tb.getClass().getName()); }
2、@Autowired不可以注解的类型:
因为@Autowired是由Spring BeanPostProcessor处理的,所以不能在自己的BeanPostProcessor或BeanFactoryPostProcessor类型应用@Autowired注解,这些类型必须通过xml或者@Bean注解形式加载。
四、@Autowired与JSR-250提供的@Resource注解的区别
1、先说@Autowired注解:
@Autowired是Spring提供的注解,需导入Package:org.springframework.beans.factory.annotation.Autowired;
@Autowired用在setter和构造器上只按照byType注入,用在成员变量field上,先按照byName注入,找不到则按照byType注入;
结合@Qualifier注解,可让setter和构造器实现byName匹配注入。
2、再说@Resource注解:
@Resource由J2EE提供,需导入javax.annotation.Resource;
@Resource有两个中重要的属性:name和type ,Spring将name属性解析为bean的名字,type属性解析为bean的类型。所以如果使用name属性,则按照byName自动注入,使用type属性则按照byType自动注入。如果既不指定name也不指定type属性,这时将通过反射机制默认使用byName自动注入。@Resource自动装配注入顺序如下:
(1). 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常;
(2). 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常;
(3). 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常;
(4). 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配。
@Resource分别可以用在field、setter上,无法应用在constructor构造器上
//用于field字段@Resourceprivate TestBeanInterface testBean;//用于setter@Resource(name = "testBean1")public void setTestBean(TestBeanInterface t){ this.testBean = t;}
注:@Resource放在setter方法上,setter方法的参数必须是一个参数,如果是多参数,则抛出如下异常:
...org.springframework.beans.factory.BeanCreationException: Error creating bean with name ......Caused by: java.lang.IllegalStateException: @Resource annotation requires a single-arg method:...
如果需要多参数setter或者构造器注入,还需要替换为@Autowired结合@Qualifier实现。
3、补充:集合或Map类型bean,无法通过@Autowired注解注入,因为没有类型匹配到这样的bean,必须通过@Resource注解注入,通过唯一名称引用集合或Map类型bean
五、JSR-330注解@Inject、@Name使用介绍
1、spring3.0开始支持JSR330标注注解,使用JSR330需要引入javax.inject包,使用maven引入:
<!-- 引入对JSR330的注解支持包 --> <dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency>
2、@Inject:
等效于@Autowired,可以用于成员变量属性、setter方法、构造器,包括匹配注入情况和抛出异常情况,可以互换使用,代码实例参照上面@Autowired注解。
3、@Named:
如果想使用特定名称进行依赖注入,可以使用@Named,此时与@Quarlifier注解作用相同。
@Inject private UserDao userDao1; @Autowired @Named("userDao2") private UserDao userDao2; @Inject @Named("userDao2") public void setUserDao2(UserDao ud2){ this.userDao2 = ud2; } @Inject public UserServiceImpl(@Named("userDao1")UserDao ud1){ this.userDao1 = ud1; }
用在类上,与@Component注解作用是等效的。
@Named("tb")public class TestBean { @PostConstruct public void start(){ System.out.println("TestBean 初始化。。。"); } @PreDestroy public void cleanUp(){ System.out.println("TestBean 销毁。。。"); }}
- Spring整理系列(10)——@Autowired自动装配、结合@Qualifier过滤及与JSR-250@Resource注解、JSR-330@Inject注解的区别、@Named使用
- Spring-基于java的标准注解装配-@Inject和@Named与@autowired和@ Qualifier区别
- Spring @Resource、@Autowired、@Qualifier的注解注入及区别
- Spring @Resource、@Autowired、@Qualifier的注解注入及区别
- Spring @Resource、@Autowired、@Qualifier的注解注入及区别
- Spring @Resource、@Autowired、@Qualifier的注解注入及区别 .
- Spring Resource、Autowired、Qualifier的注解注入及区别
- Spring @Resource、@Autowired、@Qualifier的注解注入及区别
- Spring中@Resource、@Autowired、@Qualifier的注解注入及区别
- Spring @Resource、@Autowired、@Qualifier的注解注入及区别
- Spring @Resource、@Autowired、@Qualifier的注解注入及区别
- Spring @Resource、@Autowired、@Qualifier的注解注入及区别
- Spring @Resource、@Autowired、@Qualifier的注解注入及区别
- Spring @Resource、@Autowired、@Qualifier的注解注入及区别
- Spring @Resource、@Autowired、@Qualifier的注解注入及区别
- Spring @Resource、@Autowired、@Qualifier的注解注入及区别
- Spring @Resource、@Autowired、@Qualifier的注解注入及区别
- Spring @Resource、@Autowired、@Qualifier的注解注入及区别
- 用户空间与内核空间,进程上下文与中断上下文[总结]
- JAVA第一个小项目——五子棋的制作(第一篇)
- TortoiseSVN小乌龟,忽略Android studio的一些文件和文件夹
- Android深究之序列化
- Android基础——拍照获取图片、图库获取图片、截图功能、图片模糊问题、Uri为空处理、Uri与Bitmap转换
- Spring整理系列(10)——@Autowired自动装配、结合@Qualifier过滤及与JSR-250@Resource注解、JSR-330@Inject注解的区别、@Named使用
- HDU 5774 Where Amazing Happens(水~)
- es 主要内存使用大户
- 最短的名字(简单字典树)
- Java实现读数字的问题,输入长整型数字,输出汉语里面的读法
- PowerDesigner16中的对象无效,不允许有扩展属性 问题的解决
- Android学习笔记041之屏幕适配
- 反射
- mui下拉加载更多