在Spring中,对象无需自己查找或创建与其关联的其他对象,而是由容器进行对象的“装配”,这就是Spring中依赖注入的本质。我们可以通过在代码中加入一些注解或配置自动装配Bean,实现自动化装配需要以下两步:
创建Bean并能在容器中注册;
自动满足Bean之间的依赖。
创建Bean并能在容器中注册
要创建能在容器中被发现的Bean,首先要在对应的类上使用@Component
(或@Controller
、@Repository
、@Service
)注解,使其称为一个Spring的Bean,其名称为类名。 例如我们将@Service
注解加到如下实现类上
@ServicepublicclassEmployeeServiceImplimplementsEmployeeService{//...}
在查看Spring容器中加载了哪些类
@TestpublicvoidgetAllBeans(){String[]beans=applicationContext.getBeanDefinitionNames();for(StringbeanName:beans){Class<?>beanType=applicationContext.getType(beanName);System.out.println("BeanName:"+beanName);System.out.println("Bean的类型:"+beanType);System.out.println("Bean所在的包:"+beanType.getPackage());}}
得到了如下的输出
BeanName:employeeServiceImplBean的类型:classcom.meituan.finance.account.biz.impl.EmployeeServiceImplBean所在的包:packagecom.meituan.finance.account.biz.impl
可以发现Bean的名称默认为类名的小驼峰命名。 我们也可以,通过使用@Service("empService")
或Named("empService")
自定义Bean的名称为empService
当bean生成之后我们需要让Spring容器能够在启动时发现并进行管理,就需要启用组件扫描 使用@ComponentScan
注解可以启用Bean组件的扫描,默认情况下扫描所在类相同的包,或者在XML中进行配置
<context:component-scanbase-package="com.meituan.finance.account"/>
自动满足Bean之间的依赖
Spring提供了@Autowried
注解用于进行Bean的自动装配,可以用于属性、构造方法和set方法上。在启动spring IoC时,容器自动装载了一个AutowiredAnnotationBeanPostProcessor
后置处理器,当容器扫描到@Autowied
、@Resource
(CommonAnnotationBeanPostProcessor
后置处理器处理的)或@Inject
时,就会在IoC容器自动查找需要的bean,并装配给该对象的属性 在使用@Autowired
时,首先在容器中查询对应类型的bean
如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据
如果查询的结果不止一个,那么@Autowired会根据名称来查找。
如果查询的结果为空并且required=false(more),那么会抛出异常。
Spring官方推荐将其应用在构造方法上,定义一个全参的构造方法后,对其加上@Autowired
注解,实际上这个注解可以省略:
当一个类只有一个构造函数时,可以省略
@Autowired
的注解。
对构造方法加入注解,有以下优点
允许声明不可变域,即使用final
修饰。
容易遵循单一职责设计原则。
注入的顺序更靠前
Java变量的初始化顺序:
静态变量或静态语句块
实例变量或初始化语句块
构造方法
@Autowired装配的对象