bean的创建
单例的bean是容器启动的时候创建对象,多实例的bean是每次获取的时候才创建给容器中注册一个bean:
- 包扫描+组件注解
@ComponentScan(basePackages = “com.ofo.test”) + @Controller … - @Configuration + @Bean
1和2都有一个局限性: 想引入jar包里的组件,无法通过此2种方法实现 - @Import 快速导入一个组件
3.1 @Import({Xxx.class}),容器就会自动注册这个组件,id默认是全类名
3.2 实现ImportSelector接口,这个接口的返回值就是需要注册到容器中的全类名
3.3 实现ImportBeanDefinitionRegistrar接口 - 使用Spring提供的FactoryBean接口
@Bean
public XxxFactoryBean xxxFactoryBean () {
return new XxxFactoryBean()
}
实际向容器中注册的是XxxFactoryBean中getObject()方法返回的对象
bean的初始化和销毁
我们可以自定义bean的初始化和销毁方法,容器在bean进行到当前生命周期的时候,会调用我们自定义的初始化和销毁方法,注意: 只对单例的bean生效
- 指定初始化和销毁方法
@Bean("initMethod"="init","destroyMethod"="destory")
public Xxx xxx() {
return new Xxx();
}
- 让bean实现InitializingBean接口,定义初始化方法
bean实现DisposableBean接口,定义销毁方法 - 利用JSR250提供的两个注解:
初始化: @PostConstract ,在bean完成装配之后执行
销毁: @PreDestory:在容器销毁bean之前执行
这两个注解是通过:BeanPostProcessor实现的
BeanPostProcessor——>InstantiationAwareBeanPostProcessor
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
InitDestroyAnnotationBeanPostProcessor.LifecycleMetadata metadata = this.findLifecycleMetadata(bean.getClass());
try {
metadata.invokeInitMethods(bean, beanName);
return bean;
} catch (InvocationTargetException var5) {
throw new BeanCreationException(beanName, "Invocation of init method failed", var5.getTargetException());
} catch (Throwable var6) {
throw new BeanCreationException(beanName, "Failed to invoke init method", var6);
}
}
- 实现BeanPostProcessor接口(bean后置处理器),注意: 这个处理器会处理所有的bean
postProcessBeforeInitialization:初始化之前执行
postProcessAfterInitialization:初始化之后执行
IOC容器中的bean赋值,注入其他组件,生命周期注解,@Autowired注解,@Async注解都是通过BeanPostProcessor实现的
执行顺序:
postProcessBeforeInitialization…
PostConstruct…
InitializingBean…
postProcessAfterInitialization…
PreDestroy…
DisposableBean…