Spring中bean浅析
bean:被Spring容器管理的对象
Spring容器创建
1、通过加载文件(FileSystemXmlApplicationContext(“absolute path”))
2、通过classpath的方式创建(ClassPathXmlApplicationContext(“classpath:relative path”))
3、web工程,以listener、servlet或filter方式创建
Spring注入:Spring容器在初始化时,加载bean配置信息,完成对象的创建和属性赋值
1、setter方法注入(配置spring.xml文件)
2、构造方法注入(配置spring.xml文件)
3、注解方式注入(spring.xml文件中添加扫描路径,无需配置bean等,注解内部的链接发是&&和||){
其中标识类为Bean的注解有:(bean注解的使用,需要在spring.xml中配置标签<context:component-scan base-package="your package"/>,该标签定义了spring容器扫描路径的配置,即spring容器对该路径下有使用注解类加载到spring容器中)(这些注解都标识了@Component这个元注解,并且都有value()方法,这里的value就相当于xml配置中的id)
- @Configuration(与@Bean配合使用,被标识的类内部有一个或多个@Bean标识的方法,用来替换xml配置文件)
- @Component(元注解@Component(“value”)标识bean name;一般用于工具类)
- @Repository(一般用于数据库持久层)
- @Service(用于业务层,标识bean为业务处理类)
- @Controller(web层,标识http请求入口类)
通过注解使成员属性获取变量值的有:
- @Autowired(对类成员变量,setter方法及构造函数上标注,完成自动装配工作,消除set代码和xml配置,通过AutowiredAnnotationBeanPostProcessor类回调完成)(需配置component-scan扫描路径,同上)(不止可以注入应用程序代码中出现的bean,也可以注入spring框架本身产生的bean对象)(也可以植入List属性对象到bean里,注入所有实现目标接口的类,如下)(也可注入Map,key=类名,value=对象)
- @Resource(类似于@Autowired和@Qualifier配合使用,spring容器可以指定bean name的对象注入到某个bean中,但只适用于成员变量、只有一个参数的setter方法上)
- @Qualifier(当spring中一个接口有多个实现类时,通过@Qualifier(“类名”),限定要注入bean的对象)(成员变量在上方标识,类方法和构造函数在变量定义前标识,如下)(也可自定义限定符注解,通过标识@Qualifier)
特殊注解
- @Scope(支持以注解的形式配置bean的作用域,默认是单例)
- scope=PROTOTYPE(spring容器每次获取的bean对象都是不一样的)
- (见Bean配置项)(如下)
- @Order(对被注入类进行注解)(当使用@Autowired注入到List成员变量时,可通过@Order(1)等进行排序)
- @Bean(Spring3.0版本开始,支持@Bean注解的方式来替换xml的
<bean/>
标签,用@Bean所注解的方法的类头上仅能使用@Component来标识,如下)
- @ImportResource(可以适当简化配置外部引入文件时的xml的配置文件)
- @Value(标识在字段、方法或构造函数上,指定受影响参数的默认表达式,通常用于依赖注入,还支持动态解析处理程序方法入参)
- @Value使用两种占位符:#和$
- 使用#{bean.prop}的方式,是获取bean的属性值
- 使用${properties.prop},是获取配置文件的值
- (@ImportResource和@Value示例如下)
}
spring对JSR支持
- @Resource (作用于成员属性和setter方法上(被注入),该注解有两个重要属性,name和type,如果指定了name属性值,则spring根据byName注入,如果指定type属性,则spring根据byType注入。如果同时都没有指定name和type,则spring会先根据属性名或setter方法名查找bean,查找不到时再根据byTpe方式查找注入 )
- @PostConstruct 作用于方法上,类似于@Bean init-method
- @PreDestroy 作用于方法上,类似于@Bean destory-method
spring对javax.inject支持
- @Inject 类似于@Autowired注解,作用于成员属性,构造函数,方法上
- @Named 类似于@Component注解,定义类被spring管理,且可以定义beanName
- @Qualifier和spring的@Qualifier类似,如果有多个bean子类继承同个接口,spring容器不知道要注入哪个bean时,可以通过@Qualifier指定注入的子类
spring.xml中Bean的配置项
- id 声明对象的id值,可以通过BeanFactory.getBean("id")的方式获取到bean对象,是唯一标识
- class 必填项spring容器通过getBean(Bean.class)获取bean对象
- scope bean的作用域(singleton:容器中创建时只存在一个实例,所有引用此bean都是单一实例;prototype:spring容器调用bean时,每调用一次就创建移除实例对象;request:web应用中,每一次request请求都会创建一次实例对象;session同上)
- autowired bean自动装配方式
- layz-init 懒加载模式
- init-method 初始化方法(在容器初始化bean对象的时候会执行的方法)
- destroy-method销毁方法(同上)
- 补:bean的初始化的销毁方法除了在bean中定义,还可以在beans元素标签里全局定义,使用beans里的属性:default-init-method,default-destroy-method
- 补:销毁和实现也可以通过类集成并实现InitializingBean、DisposableBean接口实现,接口优先级高于xml定义
Spring bean的生命周期
- 定义 通过xml配置单方式或者注解方式定义bean
- 初始化 Spring容器在初始化bean对象的时候执行的方法
- 使用 Spring容器获取bean对象
- 卸载 Spring容器关闭或者销毁bean的时候调用的方法
Aware接口
- aware接口:标记超级接口,实现后,可用于获取spring容器中的特殊资源对象,如BeanNameAware接口是为了让自身Bean能够感知到,以获取自身在Spring容器中的id属性;
- ApplicationContextAware接口类,能够获取到ApplicationContext对象,再通过ApplicationContext#getBean方法获取
- ApplicationEventPublisherAware接口类,提供事件发布与监听功能(发布和监听协议、事件发布者、事件监听者、事件类)
- 1、定义数据模型pojo
- 2、定义事件类,被发表的对象(继承ApplicationEvent)
- 3、事件发布者(@Service、实现ApplicationEventPublisherAware接口)
- 4、事件监听者(@Component、实现ApplicationListener<UserEvent>接口)(由于时间监听会被spring容器回调通知,因此事件监听类必须被spring管理,即注册为bean对象)
- ServletContextAware接口类,获取servletContext,获取上下文配置信息
- ResourceLoaderAware接口类,获取ResourceLoader对象
- BeanFactoryAware接口类,获取到BeanFactory实现获取bean对象信息
- MessageSourceAware接口类,得到MessageSource从而得到文本信息
- ServletConfigAware接口类,得到ServletConfig对象,获取servlet配置信息
Spring bean装配方式(初始化,如:下图可指定对另一个bean(ClassRoom)的引用,且classRoom Bean的id名要与Student类中的属性名一致)
- 自动装配方式
- autowire五种模式
- no 默认的方式是不进行自动装配,通过手工设置ref 属性来进行装配bean
- byName 通过参数名 自动装配,如果一个bean的name 和另外一个bean的 property 相同,就自动装配。
- byType 通过参数的数据类型自动自动装配,如果一个bean的数据类型和另外一个bean的property属性的数据类型兼容,就自动装配(不要求id匹配)
- construct 构造方法中的参数通过byType的形式,自动装配。(无需setter方法,转而以byType的形式通过装配Student类构造方法的参数实现)
- default 由上级标签<beans>的default-autowire属性确定
- 手动装配方式
- 在spring.xml中需手动写入property引入classRoom对象
- 以上两种方式都需要对属性设置setter方法(autowired配置如下)
Resource:接口(提供对资源访问的接口,继承Resource接口常用子类如下)
- UrlResource 用于访问http文件,ftp等目标资源
- ClassPathResource 对类路径下的资源文件进行访问解析
- FileSystemResource 对File资源或者本地系统文件解析,同样,它也支持URL。
- ServletContextResource ServletContext封装的资源,用于访问ServletContext环境下的资源
- InputStreamResource 对输入流资源访问解析
- ByteArrayResource 对字节数组资源的访问解析
- ResourceLoader接口: 实现该接口,可以获取到指定路径的资源文件信息(所有的ApplicationContext都继承自ResourcesLoader接口)
- Resource属性依赖注入(spring.xml配置如下)
- MyResource实现ResourceLoaderAware接口,获取ResourceLoader对象(Resource对象)
component-scan配置定义
- base-package 定义spring 包扫描路径
- name-generator 自定义bean name生产器,需继承自BeanNameGenerator
- use-default-filters 使用默认过滤器,默认值true
- exclude-filter 排除过滤器
- include-filter 导入过滤器(可让spring识别并加载到spring容器中,如下)
- 1、自定义java注解MyAnnotation
- 2、spring.xml配置,配置include-filter标签元素:
从外部配置文件引入属性值,以注入到Bean
spring泛型注入
- 泛型依赖注入,将可重复的代码封装到同一个基类中,由子类继承实现这个基类,通过泛型约束和定义子类的特性。
初始化
1、定义包扫描路径
2、加载配置文件 Spring通过
3、扫描包并将加载bean 通过
4、创建bean实例 通过
5、给bean实例的属性赋值 通过