spring容器:AnnotationConfigApplicationContext、组件添加、组件赋值、组件注入、AOP、声明式事务
扩展原理:
BeanFactoryPostProcessor、BeanDefinitionRegisterPostProcessor、ApplicationListener、spring容器创建过程
导入依赖:spring-context、spring-aop、spring-bean、spring-core、Commons-logging、spring-expression
组件注册
注解式开发
配置类 config == 等同于配置文件
@Configuration 告诉spring这是一个配置类
@Bean 给容器注册一个Bean,类型为返回值类型,id默认是用方法名作为id
Scope指定作用范围:
ConfigurableBeanFactory#SCOPE_PROTOTYPE – prototype
ConfigurableBeanFactory#SCOPE_SINGLETON – singleton
org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST – request
org.springframework.web.context.WebApplicationContext#SCOPE_SESSION – session
Scope最常用的范围:
prototype:多实例。IOC容器启动不会调用方法创建对象放在容器中,
每次获取的时候会调用方法创建对象,每次调用每次创建
singleton:单实例(默认)。IOC容器启动会调用方法创建对象放到IOC容器中
,以后每次获取都是直接从容器(map.get())中拿
request:同一个请求创建一个实例(Web)
session:同一个session创建一个实例(Web)
懒加载(针对单实例bean):
单实例bean,默认在容器启动的时候创建对象
懒加载:容器启动不创建对象,第一次使用(获取)Bean创建对象,并初始化。
@Bean("Bill")
public Student student02(){
return new Student("Bill Gates","62");
}
/**
* 这是一个注解类
* 注解类 == 配置文件beans.xml
*
* @ComponentScan value:是指定要扫描的包
* excludeFilters = Filter[] :指定扫描的时候按照扫描规则排除哪些组件
*
* FilterType.ANNOTATION 按照注解类型扫描(最常用的方式)
* FilterType.ASSIGNABLE_TYPE 按照给定规则扫描
* FilterType.ASPECTJ 按照ASPECTJ的表达式扫描
* FilterType.REGEX 按照正则表达式进行扫描
* FilterType.CUSTOM 按照自定义方式进行扫描
*
*
* includeFilters = Filter[] :指定扫描的时候需要包含哪些组件
* 使用包含组件时需要加上useDefaultFilters = false
*
* 在@ComponentScans中可以加入多个@ComponentScan
* */
@Configuration
@ComponentScans(
@ComponentScan(value = "com.Liuxu",includeFilters = {
/*@ComponentScan.Filter(type = FilterType.ANNOTATION , classes = {
Controller.class
})*/
@ComponentScan.Filter(type = FilterType.CUSTOM , classes = {MyTypeFilter.class})
},useDefaultFilters = false)
)
/**
* @Conditional : 按照一定的条件进行判断,满足条件给容器中注册bean
*
* 如果系统是Windows,给容器中注册("Bill")
* 如果系统是Linux,给容器中注册("linus")
*
* */
@Conditional({WindowsCondition.class})
总结: 给容器中注册组件:
1.包扫描+组件标注注解(@Controller、@Service、@Repository、@Component)
2.@Bean 导入第三方包里面的组件
3.@Import 快速给容器中导入一个组件
1)@Import(要导入到容器中的组件),容器中就会自动注册这个组件,id默认是全类名
2)ImportSelector:返回需要导入的组件的全类名数组
3)ImportBeanDefinitionRegistrar:手动注册bean到容器中
BeanDefinitionRegistry:BeanDefinition注册类 :把所有需要添加到容器的bean,调用BeanDefinitionRegistry.registerBeanDefinition手工注册进来
注册一个Bean,指定bean名;指定bean定义信息,Bean的类型等
4.使用spring提供的FactoryBean(工厂Bean)
创建一个spring定义的FactoryBean。单实例会在容器中保存一份,多实例每次都会创建一个新的bean
工厂bean获取的是调用getObject创建的对象。
1)默认获取到的是工厂bean调用getObject创建的对象
2)要获取弓藏Bean本身,我们需要给id前面加一个& --> &colorFactoryBean
生命周期
/**
* bean声明周期:
* bean创建 -- 初始化 -- 销毁过程
* 容器管理bean的生命周期
* 我们可以自定义初始化和销毁方法,容器在bean进行到当前声明周期的时候拉力调用我们自定义的初始化和销毁方法
*
* 构造(对象创建):
* 单实例:在容器启动的时候创建对象
* 多实例:在每次获取的时候创建对象
* 初始化:
* 对象创建完成,并赋值好,调用初始化方法
* 销毁:
* 单实例:在容器关闭的时候进行销毁
* 多实例:容器不会管理这个bean,所以容器不会调用销毁方法
*
*
*
* 1)指定初始化和销毁方法 -- car
* 在beans文件中指定init-method 和 destroy-method方法
* 通过@Bean指定initMethod和destroyMethod
*
* 2)通过让Bean实现InitializingBean(定义初始化逻辑),DisposableBean(定义销毁容器)--cat
* 3)可以使用JSR250: --dog
* @PostConstruct:在bean创建完成并且属性赋值完成,来执行初始化
* @PreDestroy:在容器销毁之前通知我们进行清理工作
* 4)BeanPostProcessor[interface]:bean的后置处理器 -- MyBeanPostProcessor
* 在bean初始化前后进行一些处理工作
* postProcessBeforeInitialization:在初始化之前工作
* PostProcessAfterInitialization:在初始化之后工作
* 遍历得到容器中所有的BeanPostProcessor,挨个执行beforeInitialization,一旦返回null,
* 就跳出for循环,不会执行后面的BeanPostProcessor。
*
*
* */