一、Spring IOC Bean 的三种配置方式:
1、XML声明配置
顾名思义,就是将bean的信息配置.xml文件里,通过Spring加载文件为我们创建bean和配置bean属性
2、注解声明配置
通过在类上加注解的方式,来声明一个类交给Spring管理,Spring会自动扫描带有@Component,@Controller,@Service,@Repository这四个注解的类,然后帮我们创建并管理,前提是需要先配置Spring的注解扫描器。
- @Component:可以用于注册所有bean
- @Repository:主要用于注册dao层的bean
- @Controller:主要用于注册控制层的bean
- @Service:主要用于注册服务层的bean
3、JavaConfig声明配置
将类的创建交给我们配置的JavcConfig类来完成,Spring只负责维护和管理创建一个配置类
- 添加@Configuration注解声明为配置类
- 方法上加上@bean,该方法用于创建实例并返回
二、Spring IOC Bean 的三种注入方式:
Spring通过DI(依赖注入)实现IOC(控制反转),常用的注入方式主要有三种:构造方法注入,setter注入,基于注解的注入。
接口注入(不使用)
在接口中定义要注入的信息,并通过接口来完成注入。(Spring不支持这种注入方式--不支持的原因是--Spring声称其是非入侵式的《离开这个框架也能活》,如果使用接口注入的话,就违背了这一原则)
1、构造方法注入:constructor-arg通过构造函数注入
<bean id="userService" class="com.lyu.spring.service.impl.UserService">
<constructor-arg ref="userDaoJdbc"></constructor-arg>
</bean>
- 如果只有一个有参数的构造方法并且参数类型与注入的bean的类型匹配,那就会注入到该构造方法中。
- 只有一个构造方法,但是有两个参数,一个是待注入的参数,另一个是其他类型的参数,会抛出异常->注册失败。即使在costract-arg标签里面通过name属性指定要注入的参数名也一样
- 如果有多个有参数的构造方法并且每个构造方法的参数列表里面都有要注入的属性,会注入到只有一个参数的构造方法中,并且经过测试注入哪一个构造方法与构造方法的顺序无关
- 如果有多个构造方法,每个构造方法只有参数的顺序不同,哪个构造方法在前就注入哪一个,这种情况下就与构造方法顺序有关。
2、setter注入:property通过setter对应的方法注入
<bean id="userService" class="com.lyu.spring.service.impl.UserService">
<property name="userDao" ref="userDaoMyBatis"></property>
</bean>
spring会将name值的每个单词首字母转换成大写,然后再在前面拼接上"set"构成一个方法名,然后去对应的类中查找该方法,通过反射调用,实现注入。
切记:
1、name属性值与类中的成员变量名以及set方法的参数名都无关,只与对应的set方法名有关
2、如果通过set方法注入属性,那么spring会通过默认的空参构造方法来实例化对象,所以如果在类中写了一个带有参数的构造方法,一定要把空参数的构造方法写上,否则spring没有办法实例化对象,导致报错
3、基于注解的注入
bean的一个属性autowire,autowire主要有三个属性值:constructor,byName,byType
constructor:加在构造方法上
spring会匹配与构造方法参数类型一致的bean进行注入,如果有一个多参数的构造方法,一个只有一个参数的构造方法,在容器中查找到多个匹配多参数构造方法的bean,那么spring会优先将bean注入到多参数的构造方法中。
byName:加在字段上
被注入bean的id名必须与set方法后半截匹配,并且id名称的第一个单词首字母必须小写,这一点与手动set注入有点不同。
byType:加在set方法上
查找所有的set方法,将符合符合参数类型的bean注入
描述依赖关系主要有两种:
@Resource:java的注解,默认以byName的方式去匹配与属性名相同的bean的id,如果没有找到就会以byType的方式查找,如果byType查找到多个的话,使用@Qualifier注解(spring注解)指定某个具体名称的bean
@Autowired:spring注解,默认是以byType的方式去匹配类型相同的bean,如果只匹配到一个,那么就直接注入该bean,无论要注入的 bean 的 name 是什么;如果匹配到多个,就会调用 DefaultListableBeanFactory 的 determineAutowireCandidate 方法来决定具体注入哪个bean