概念
在Spring中可以通过配置bean标签的scope属性来指定bean的作用域范围,各取值含义如下表:
取值 | 含义 | 创建对象的时机 |
---|---|---|
singleton(默认) | 在IOC容器中,这个bean的对象始终为单实例 | IOC容器初始化时 |
prototype | 这个bean在IOC容器中有多个实例 | 获取bean时 |
如果是WebApplicatitonContext环境下还会有另外两个作用域:
取值 | 含义 |
---|---|
request | 在有关请求范围内有效 |
session | 在一个会话范围内有效 |
Bean的生命周期
-
bean对象创建(调用无参构造器)
-
给bean对象设置属性
-
bean对象初始化之前操作(由bean的后置处理器负责)
-
bean对象初始化(需在配置bean时指定初始化方法)
-
bean对象初始化之后操作(由bean的后置处理器负责)
-
bean对象就绪可以使用
-
bean对象销毁(需在配置bean时指定销毁方法)
-
IOC容器关闭
案列:
-
创建Dog类
-
交给IOC容器管理
在IOC中声明了两个方法:
init-method="initMethod":在初始化时调用initMethod
destroy-method="destroyMethod":在销毁时调用destroyMethod
-
测试类
4 测试结果
注意:
若bean的作用域为单例时,生命周期的前三个步骤会在获取IOC容器时执行
若bean的作用域为多例时,生命周期的前三个步骤时会在获取Bean时执行
bean的后置处理器
bean的后置处理器会在生命周期的初始化前后添加额外的操作,需要实现BeanPostProcessor接口,且配置到IOC容器中,需要注意的是,bean的后置处理器不是单独针对某一个bean生效,而是针对IOC容器中的所有bean都会执行
创建bean的后置处理器:
在xml文件中加入ioc容器
<bean id="myBeanPostProcessor" class="com.my.processor.MyBeanPostProcessor"></bean>
结果:
自动装配(autowire)
根据指定的策略,在IOC容器中匹配某一个bean,自动为指定的bean中所依赖的类类型或接口类型属性赋值。
可以通过bean标签中的autowire属性设置自动装配的策略
自动装配的策略:
no,default:表示不装配,即bean 中的属性不会自动匹配某个bean为属性赋值,此时属性使用默认值
byType
根据要赋值的属性的类型,在IOC容器中匹配某个bean,为属性赋值
-
若通过类型没有找到任何一个类型匹配的bean,此时不装配,属性使用默认值
-
若通过类型找到了多个类型匹配的bean,此时会抛出异常:NoUniqueBeanDefinitionException
当使用byType实现自动装配时,IOC容器中有且只有一个类型匹配的bean能够为属性赋值。
注意:通过byType装配,装配的bean类型要只有一个该类型的bean
byName
将要赋值的属性的属性名作为bean的id在IOC容器中匹配某个bean,为属性赋值
-
如果通过属性名没有找到任何一个id匹配的bean,此时不装配
当类型匹配的bean有多个时,此时可以使用byName实现自动装配
<!-- context:exclude-filter:排除扫描 type:设置排除扫描的方式 type="annotation|assignable" annotation:根据注解的类型进行排除,expression需要设置排除的注解的全类名 assignable:根据类的类型进行排除,expression需要设置排除的类的全类名 context:include-filter: 包含扫描 注意:需要在context:component-scan标签中设置use-default-filters="false" use-default-filters="true"(默认),所设置的包下所有的类都需要扫描,此时可以用排除扫描 use-default-filters="false",所设置的包下所有的类都不需要扫描,此时可以用包含扫描 --> <!-- 扫描组件 --> <context:component-scan base-package="com.atguigu.spring"></context:component-scan> <!--<context:component-scan base-package="com.atguigu.spring" use-default-filters="false"> <!– 排除 –> <!–<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>–> <!–<context:exclude-filter type="assignable" expression="com.atguigu.spring.controller.UserController"/>–> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>--> <!--<bean id="service" class="com.atguigu.spring.service.impl.UserServiceImpl"></bean> <bean id="dao" class="com.atguigu.spring.dao.impl.UserDaoImpl"></bean>-->
通过注解+扫描所配置bean的id,默认值为类的小驼峰,即类名的首字母为小写的结果 * 自定义Id 可以通过标识组件的注解的value属性值设置bean的自定义的id * * @Controller:控制层 * @Service:业务层 * @Repository:持久层 * @Component:声明为组件 * 上面四个组件的功能都一样,只是为了让开发人员更好分辨每个类的功能 * @AutoWired:实现自动装配的注解 * 1.@AutoWired注解能够标识的位置 * a>标识在成员变量上,此时不需要设置成员变量的set方法 * b>标识在set方法上 * c>为当前变量赋值的构造方法上 * 2.@Autowired注解的原理 * a>默认通过byType的方式,在IOC容器中通过类型匹配某个bean为属性赋值 * b>若头多个类型匹配的bean,此时会自动转换为byName的方式实现自动装配的效果 * 即将要赋值的属性的属性名作为bean的id匹配某个bean为属性赋值 id和属性名一致 * c>若byType和byName的方式都无法实现自动装配,即IOC容器中有多个类型匹配的bean * 且这些bean的id和要赋值的属性的属性名都不一致,此时抛出异常:NoUniqueBeanDefinitionException * d>此时可以在要赋值的属性上,添加一个注解@Qualifier * 通过该注解的value属性值,指定某个bean的id,将这个bean为属性赋值 * * 注意:若IOC容器中没有任何一个类型匹配的bean,此时抛出异常NoSuchBeanDefinitionException * 在@Autowired注解中有个属性required,默认值为true ,要求必须完成自动装配 * 可以将required设置为false,属性使用默认值