一、装配
1.1、一些概念
- 创建应用对象之间的协作关系的行为通常称为装配,这也是依赖注入的本质。
- Spring的三种装配机制:
- (1)、在xml中进行显示装配
- (2)、在java中基于javaConfig进行显示的装配
- (3)、隐式的Bean发现机制和自动装配(注解的方式)
1.2、自动化装配
- (1)、Spring从两个角度实现自动化装配
- 组件扫描:Spring会自动发现应用上下文中所创建的Bean
- 自动装配:Spring自动满足Bean之间的依赖
- (2)、注解:
- @Component:表明该类为组件类,并告知Spring要为这个类创建Bean
- @ComponentScan:启用了组件扫描(默认不启用),在需要装配其他类的类中添加该注解。这个默认扫描与配置类相同的包。
- @Component(“xxxname”)/@Name(“xxxname”):为组件扫描的Bean命名,为beanId
- @ComponentScan(“xxxpack”)、@ComponentScan(basePackages={“xxxpack1”,“xxxpack2”}):设置基础包,代码启动扫描组件需要扫描那些包中带@Component注解的类。基础包的设置是不安全的,假如重构会是包结构变化,还有一种直接指定类或者接口进行扫描的方式**@ComponentScan(basePackagesClasses={“xxxclass1”,“xxxclass2”})**
- @Autowried(@Inject、@Named):声明需要进行自动装配,会在Spring应用上下文中去寻找匹配某个Bean需求。这个注解不仅能够用在构造器的方法上,还可以用在setter方法上。若没找到Bean会抛出异常。@Autowried(required=false),这种声明方式,先尝试去执行自动装配,若没找到对应的Bean,则会让这个Bean处于未装配的状态。
1.3、通过java代码装配bean
-
(1)、使用场景:第三方库中的组件装配,因为没有办法直接在组件中添加@Component和@Autowired注解。
-
(2)、方式:
- 创建配置类,添加**@Configuration**注解
- 声明简单的bean,需要编写方法,这个方法会创建所需类型的实例,然后给这个方法添加**@Bean**、**@Bean(name=“xxxname”)**的注解。(该注解会告诉Spring这个方法会返回一个对象,这个对象要注册为Spring应用上下文中的bean)
@Bean public CompactDisc sgtPpers(){ return new sgtPpers();//这个bean的声明很简单,没有添加其他任何依赖 }
@Bean public CDPlayer cdPlayer(){ return new cdPlayer(sgtPpers());//这个bean的声明需要依赖CompactDisc对象的构造器来创建cdPlayer实例 }
- 看起来了,这个时候CompactDisc是通过调用sgtPpers()方法得到的,但是因为sgtPpers()上添加@Bean的注解,所以Spring会拦截所有对它的调用,并确保直接返回该方法创建的bean,而不是每次都对其进行实际的调用。
1.4、通过xml装配bean
-
(1)、构造器的注入
- xml声明bean源的时候,设置的属性:class属性,类的全名;id属性,指定的beanId。
- xml中声明DI的两种风格:
- (1)、< construtor-arg >元素
- (2)、c-命名空间。相对第一种方式更强大,支持list、set、map类型的引用。
<bean id = "compactDisc" class = "soundsystem.SgtPppers"/> <bean id = "cdPlayer" class = "soundsystem.CDPlayer"> <constructor-arg ref = "compactDisc"> </bean> <bean id = "cdPlayer" class = "soundsystem.CDPlayer"> c:cd-ref = "compactDisc" </bean>
- 当spring遇到< bean >元素时,会创建一个CDPlayer的实例,constructor-arg元素会告知spring要将一个ID为compactDisc的bean引用传递到CDPlayer的构造器中。
<bean id = "compactDisc2" class = "soundsystem.BlankDisc"> <constructor-arg value = "属性1"> <constructor-arg value = "属性2"> </bean> <bean id = "compactDisc2" class = "soundsystem.BlankDisc"> c:_title = "属性1"> c:_artist = "属性2"> </bean>
- 字面量的装配,可以将参数带入有参构造器中创建实例
<bean id = "compactDisc2" class = "soundsystem.BlankDisc"> <constructor-arg value = "属性1"> <constructor-arg value = "属性2"> <constructor-arg> <list> <value>11</value> <value>22</value> <value>33</value> <value>44</value> </list> </constructor-arg> </bean>
- 装配集合的方式
-
(2)、属性的注入
- 一般来说,对于强依赖使用构造器注入,对于可选性的依赖使用属性的注入
<bean id = "cdPlayer" class = "soundsystem.CDPlayer"> <property name = "compactDisc" ref = "compactDisc"/> </bean> <bean id = "cdPlayer" class = "soundsystem.CDPlayer"> p:compactDisc-ref = "compactDisc"/> </bean>
<bean id = "cdPlayer" class = "soundsystem.CDPlayer"> <property name = "titile" value = "111"/> <property name = "artist" value = "222"/> <property name = "artist"> <list> <value>11</value> <value>22</value> </list> </property> </bean>
二、注入
2.1、注入的方式:
- 使用属性的setter方法注入 这是最常用的方式;
- 使用构造器注入;
- 使用Filed注入(用于注解方式)
2.2、注解的方式注入:
- 使用@Autowired或@Resource注解方式进行Spring的依赖注入
- @Autowired是按照类型的方式注入
- @Resource默认按名称装配,当找不到与名称匹配的bean时,才会按类型装配。