@Autowired用法与原理解析
Posted 流楚丶格念
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了@Autowired用法与原理解析相关的知识,希望对你有一定的参考价值。
文章目录
@Autowired 注解用法
@Autowired 注解,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。 通过 @Autowired的使用来消除 set ,get方法。
在使用@Autowired之前,我们对一个bean配置起属性时,是这样用的:
<property name="属性名" value=" 属性值"/>
通过这种方式来,配置比较繁琐,而且代码比较多。在Spring 2.5 引入了 @Autowired 注解。
下面用案例来具体说明一下@Autowired的用法
代码案例
定义Bean的接口,其中定义了一个save方法
package com.yyl.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService
@Autowired
private UserRepository userRepository;
public void save()
userRepository.save();
定义一个UserRepository接口的实现类,并实现save方法,注意,在这里指定了该bean在IoC中标识符名称为userRepository,后面我们使用的时候可以从容器上下文中获取
package com.yyl.service.impl;
import com.yyl.service.UserRepository;
import org.springframework.stereotype.Repository;
// 指定了该bean在IoC中标识符名称为userRepository
@Repository("userRepository")
public class UserRepositoryImpl implements UserRepository
@Override
public void save()
System.out.println("UserRepositorUImpl save");
然后我们定义服务类,这里需要一个UserRepository类型的属性实例,通过@Autowired自动装配方式,从IoC容器中去查找到,并返回实例
package com.yyl.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService
@Autowired
private UserRepository userRepository;
public void save()
userRepository.save();
然后需要在 applicationContext.xml配置注解扫描的包
<!--配置扫面-->
<!--配置扫描带有四大注解类:@Controller、@Service、@Repository、@Component,交给spring统一管理-->
<context:component-scan base-package="com.yyl.service"></context:component-scan>
测试代码:
@Test
public void AutowiredBean()
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService=(UserService) ctx.getBean("userService");
userService.save(); //结果为UserRepositoryImps save
运行结果如下所示:
@Autowired的原理
其实在启动spring IoC时,容器自动装载了一个AutowiredAnnotationBeanPostProcessor
后置处理器,当容器扫描到@Autowied、@Resource或@Inject时,就会在IoC容器自动查找需要的bean,并装配给该对象的属性
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
装配过程如下所示:
然后我们在使用@Autowired时,首先在容器中查询对应类型的bean。如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据如果查询的结果不止一个,那么@Autowired会根据名称来查找。如果查询的结果为空,那么会抛出异常。
解决方案:使用required=false,没有就返回空就好,不用报异常
补:@Autowired的require属性
required默认为true,如下源码
当required属性为true的时候,注入SpringBean的时候,该bean必须存在,不然会注入失败,启动报错
当required属性为false的时候,注入SpringBean的时候,如果bean存在,就注入;如果不存在,就忽略跳过,启动不会报错,但不能直接使用
代码案例:多个实现类实例
举例说明: 接着上面的例子,我们在定一个类来实现UserRepository接口
package com.yyl.service.impl;
import com.yyl.service.UserRepository;
import org.springframework.stereotype.Repository;
@Repository()
public class UserAnotherImpl implements UserRepository
@Override
public void save()
System.out.println("UserAnotherImpl save");
这时在启动容器后,在容器中有两个UserRepository类型的实例,一个名称为userRepository,另一个为UserAnotherImpl。
此时,在UserService中
@Autowired
private UserRepository userRepository; // 输出结果:UserRepositoryImpl save
运行结果:
这里由于查询到有两个该类型的实例,那么采用名称匹配方式,在容器中查找名称为userRepository
的实例,并自动装配给该参数。如果这里想要装配UserAnotherImpl
的实例,除了可以将字段userRepository
名称改成UserAnotherImpl
外,还可以提供了一个@Qualifier注解,来指定需要装配bean的名称,代码如下:
我们先给UserAnotherImpl
加一个bean名称
@Repository("userAnotherImpl")
public class UserAnotherImpl implements UserRepository
@Override
public void save()
System.out.println("UserAnotherImpl save");
再修改注入时代码
@Autowired
@Qualifier("userAnotherImpl")
private UserRepository userRepository; //输出结果:UserAnotherImplsave
运行结果:
以上是关于@Autowired用法与原理解析的主要内容,如果未能解决你的问题,请参考以下文章
Spring中@Resource与@Autowired@Qualifier的用法与区别