首发于Spring

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=对象)
注入了StudentServicelmpl1、2、3到List中
  • @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.xml

}

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实例的属性赋值 通过

编辑于 2021-08-09 16:55