Spring知识(一)之基础知识(核心和装配Bean)
Spring创建应用组件之间的行为通常称为装配,Spring有很多装配的方式,xml文件的装配方式,Java注解配置方式
Spring通过应用上下文(Application Context)装载bean的定义并把它们组装起来;Spring应用上下文全权负责对象的创建和组装,Spring自带了很多应用上下文的实现,它们之间主要的区别仅仅在于如何加载配置;
应用上下文实现一:ClassPathXmlApplicationContext ,从类路径下的一个或多个XML配置文件中加载上下文定义,把应用上下文的定义文件作为类资源。使用xml方式配置的,选择该上下文实现比较合适
应用上下文实现二:AnnotationConfigApplicationContext,从一个或者多个基于java的配置类中加载Spring上下文
应用上下问实现三:AnnotationConfigWebApplicationContext,从一个或者多个基于Java的配置累中加载Spring Web应用上下文
应用文上下实现四:FileSystemapplicationcontext,从文件系统下的一个或多个XML配置文件中加载上下文定义
应用上下文实现五:XmlWebApplicationContext,从web应用新爱的一个或多个XML配置文件中加载上下文定义
Bean的生命周期:
1.Spring对Bean进行实例化
2.Spring将值和bean的引用注入到bean对应的属性中
3.如果bean实现了BeanNameAware接口,Spring将bean的ID传递给setBeanName()方法
4.如果bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入
5.如果bean实现了ApplicationContextAware接口,Spring将调用setApplicationCoontext()方法,将bean所在的应用上下文的引用传入进来
6.如果bean实现了BeanPostProcessor接口,Spring将调用它们的postProcessBeforeInitialization()方法
7.如果bean实现了InitializingBean接口,Spring将调用它们的afterPropertiesSet()方法。类似的,如果bean使用initmenthod声明了初始化方法,该方法也会被调用
8.如果bean试下了BeanPostProcessor接口,Spring将调用它们的postProcessAfterInitialization()方法
9.此时,bean已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到该应用上下文被销毁
10.如果bean实现了DisposableBean接口,Spring将调用它的destroy()接口方法。同样,如果bean使用destroymethod声明了销毁方法,该方法也会被调用
Spring模块:
spring划分为六大类不同功能,如下图
自动化装配Bean:
Spring从两个角度来实现自动化装配 组建扫描 和 自动装配
组件扫描(component scanning):spring会自动发现应用上下文中所创建的bean,在类名上使用@Component注解,表明该类会作为组件类,并告知Spring要为这个类创建bean。没有必要显示的配置。不过组件扫描默认是不开启的,还需要显示配置一下,在声明为配置类的上方再加上@ComponentScan,这个注解能够在Spring中启用组件扫描,如果没有其他配置,@ComponentScan默认会扫描于配置类相同的包。 spring支持将@Named作为@Component注解的替代方案。两者之间有一些细微的差异,但是在大多数场景中可以互相替换
标示首选的bean:在声明bean的时候,通过将其中一个可选的bean设置为首选bean能够避免自动装配的歧义性。使用注解@Primary,该注解能够与@Component组合用在组件扫描的bean上,也可以与@Bean组合用在java配置的bean声明中。
限定自动装配的bean:设置首选bean的局限性在于@Primary无法将可选方案的范围限定到唯一一个无歧义的选项中。所以需要用到Spring的限定符能够在所有可选的bean上进行缩小范围的操作,最终能够达到只有一个bean满足所规定的限制条件。
@Qualifier注解是使用限定符的主要方式。它可以与@Autowired和@Inject协同使用,在注入的时候指定想要注入进去的bean。以下代码示例:
为@Qualifier注解所设置的参数就是想要注入的bean的ID。除此之外还可以为bean设置自己的限定符,而不是依赖bean ID作为限定符。@Qualifier可以与@Component组合使用,如下所示:
以上代码中的@Qualifier注解中的cold限定符分配给了IceCream这个bean。因为它没有耦合类名,因此你可以随意重构IceCream的类名。在注入的地方,只要引用cold限定符就可以了,如下代码所示:
@Configuration:声明类为一个配置类
设置组件扫描的基础包:@Component默认会扫描于配置类相同的包。如果想要扫描不同的包可以指定包名:@ComponentScan("base")
如果想要更加清晰表明所设置的是基础包,那么可以通过basePackages属性进行配置:
@ComponentScan(basePackages="base") 也可以设置多个: @ComponentScan(basePackages={"base",'voide"'})
除了将包设置为简单的String类型之外,@ComponentScan还提供了另外一种方法,那就是将其指定为所包含的类或接口:
@ComponentScan(basePackageClasses={CDPlayer.class,DVDPlayer.class})
自动装配(autowiring):Spring自动满足bean之间的依赖。在满足依赖的过程中,会在Spring应用上下文中寻找匹配某个bean需求的其他bean。使用Spring的@Autowired注解进行自动装配。
查看以下代码清单:
在CDPlayer类上的构造器添加了@Autowired注解,这表明当Spring创建CDPlayer bean的时候,会通过这个构造器来进行实例化并且传入一个可设置CompactDisc类型的bean。
@Autowired也适用在属性的setter方法上。比如说:CDPlayer有一个setCompactDisc()方法,那么可以采用如**解形式进行自动装配:
@Autowired
public void setCompactDisc(CompactDisc cd){
this.cd= cd;
}
Spring同时支持@Inject来替换@Autowired,@Inject注解来源于java依赖注入规范
通过java代码装配bean
要在javaConfig中声明bean,编写一个方法,给这个方法添加@Bean注解,例如下面代码:
默认情况下,bean的ID与带有@Bean注解的方法名一样,如果想设置为其他名字,如下面代码:
实现注入: 在声明的CompactDisc bean是非常简单的,没有其他依赖。如果有其它bean需要依赖的话,如下配置:
cdPlayer()方法通过调用sgtPeppers()得到一个CompactDisc对象实例,但是由于sgtPeppers()方法上添加@Bean注解,Spring将会拦截所有对它的调用,并确保直接返回该方法所创建的bean,而不是每次都创建新的对象;比如说,引入了一个其他的CDPlayer bean,它和之前的那个bean完全一样,如下示例:cdPlayer()方法和anotherCDplayer()方法得到的一个CompactDisc对象都是同一个。