IOC
介绍
什么是SpringIOC,就是把每一个bean(实体类)与bean(实体类)之间的关系交给第三方容器进行管理。
关键类
BeanFactory
IOC的顶层容器,描述了IOC的规范。
BeanFactory是一个接口,是Spring中工厂的顶层规范,IOC的核心接口。
定义了getBean()、containsBean()等管理Bean的通用方法。
延迟加载,只有getbean时,才进行实例化
public interface BeanFactory {
//对FactoryBean的转义定义,因为如果使用bean的名字检索FactoryBean得到的对象是工厂生成的对象, //如果需要得到工厂本身,需要转义 String FACTORY_BEAN_PREFIX = "&";
//根据bean的名字,获取在IOC容器中得到bean实例 Object getBean(String name) throws BeansException;
//根据bean的名字和Class类型来得到bean实例,增加了类型安全验证机制。 <T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
//提供对bean的检索,看看是否在IOC容器有这个名字的bean boolean containsBean(String name);
//根据bean名字得到bean实例,并同时判断这个bean是不是单例 boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
//得到bean实例的Class类型 @Nullable Class<?> getType(String name) throws NoSuchBeanDefinitionException;
//得到bean的别名,如果根据别名检索,那么其原名也会被检索出来 String[] getAliases(String name); } |
加载过程
Xml→Resource→BeanDefinition→BeanFactroy
Resoucrce
org.springframework.core.io.Resource,对资源的抽象。它的每一个实现类都代表了一种资源的访问策略,如 ClassPathResource、URLResource、FileSystemResource 等。
ResourceLoader
有了资源,就应该有资源加载,Spring 利用 org.springframework.core.io.ResourceLoader 来进行统一资源加载
BeanDefinition
ioc 实现中 我们在xml 中描述的Bean信息最后 都将保存至BeanDefinition (定义)对象中
// BEAN描述信息 public class BeanDefinition { // 名称 private String name; // CLASS private Class<?> clazz; // 通过名称和CLASS实例化, 默认使用CLASS名作为BEAN的名称 public BeanDefinition(String name, Class<?> clazz) { this.clazz = clazz; this.name = BeanUtil.isEmpty(name) ? BeanUtil.getName(clazz) : name; } // Getter & Setter // ... } |
BeanDefinitionReader
作用是读取Spring配置文件中的内容,将之解析为BeanDefinition并注册到 BeanDefinitionRegistry工厂中。
作用是读取 Spring 配置文件中的内容,将其转换为 IoC 容器内部的数据结构:BeanDefinition。
public interface BeanDefinitionReader { //返回Bean工厂以向其注册Bean定义。 BeanDefinitionRegistry getRegistry(); /**返回资源加载器以用于资源位置。可以检查ResourcePatternResolver接口并进行相应的转换,以针对给定的 资源模式加载多个资源。 一个null返回值表明,绝对资源加载不适用于这个bean定义阅读器。 这主要用于从bean定义资源中导入其他资源,例如,通过XML bean定义中的“ import”标记。但是,建议相对 于定义资源应用此类导入;只有明确的完整资源位置才会触发绝对资源加载。 **/ @Nullable ResourceLoader getResourceLoader(); //返回用于Bean类的类加载器。 @Nullable ClassLoader getBeanClassLoader(); //返回BeanNameGenerator用于匿名Bean(未指定显式Bean名称)。 BeanNameGenerator getBeanNameGenerator(); //从指定的资源加载bean定义。 int loadBeanDefinitions(Resource var1) throws BeanDefinitionStoreException; int loadBeanDefinitions(Resource... var1) throws BeanDefinitionStoreException; //从指定的资源位置加载bean定义。 //该位置也可以是位置模式,前提是此bean定义读取器的ResourceLoader是ResourcePatternResolver。 int loadBeanDefinitions(String var1) throws BeanDefinitionStoreException; int loadBeanDefinitions(String... var1) throws BeanDefinitionStoreException; } |
BeanDefinitionReader的实现类
BeanDefinitionReader 下有一个抽象子类 AbstractBeanDefinitionReader,AbstractBeanDefinitionReader下有三个子类。
- XmlBeanDefinitionReader:读取 XML 文件定义的 BeanDefinition
- PropertiesBeanDefinitionReader:可以从属性文件,Resource,Property 对象等读取 BeanDefinition
- GroovyBeanDefinitionReader:可以读取 Groovy 语言定义的 Bean
ApplicationContext
ApplicationContext继承自BeanFactory,提供的功能更加强大
实现类
AnnotationConfigApplicationContext:从一个或多个基于java的配置类中加载上下文定义,适用于java注解的方式;
ClassPathXmlApplicationContext:从类路径下的一个或多个xml配置文件中加载上下文定义,适用于xml配置的方式;
ApplicationContext ac =new ("application.xml");
ClassPathXmlApplicationContext
ClassPathXmlApplicationContext如果没有前缀默认就是classpath
FileSystemXmlApplicationContext
ApplicationContext ac =new FileSystemXmlApplicationContext(/User/Desktop/application.xml);
FileSystemXmlApplicationContext如果没有前缀默认就是 file:
AnnotationConfigWebApplicationContext:从一个或多个基于java的配置类中加载上下文定义,适用于java注解的方式;
XmlWebApplicationContext:从web应用下的一个或多个xml配置文件加载上下文定义,适用于xml配置方式。
FileSystemXmlApplicationContext:从文件系统下的一个或多个xml配置文件中加载上下文定义,也就是说系统盘符中加载xml配置文件;
Bean声明周期
实例化 --》 InstantiationAwareBeanPostProcessor
@Component public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
// 实例化前置 @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("postProcessBeforeInstantiation被调用了----在对象实例化之前调用-----beanName:" + beanName); // 默认什么都不做,返回null return null; }
// 实例化后置 @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { System.out.println("postProcessAfterInstantiation被调用了---------beanName:" + beanName); //默认返回true,什么也不做,继续下一步 return true; }
// 属性修改 @Override public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { System.out.println("postProcessPropertyValues被调用了---------beanName:"+beanName); // 此方法可对bean中的属性值进行、添加、修改、删除操作; // 对属性值进行修改,如果postProcessAfterInstantiation方法返回false,该方法可能不会被调用, return pvs; } } |
初始化---》给容器属性赋值
public class AllAwareInterface implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware, ApplicationEventPublisherAware, MessageSourceAware, ApplicationContextAware, ServletContextAware, LoadTimeWeaverAware, ImportAware {
@Override public void setBeanName(String name) { // BeanNameAware作用:让Bean对Name有知觉 //这个方法只是简单的返回我们当前的beanName,听官方的意思是这个接口更多的使用在spring的框架代码中,实际开发环境应该不建议使用 System.out.println("1 我是 BeanNameAware 的 setBeanName 方法---参数:name,内容:"+ name); } @Override public void setBeanClassLoader(ClassLoader classLoader) { System.out.println("2 我是 BeanClassLoaderAware 的 setBeanClassLoader 方法"); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { // 注意: 如果使用 @Configuration 注解的话,setBeanFactory方法会执行2次, System.out.println("3 我是 BeanFactoryAware 的 setBeanFactory 方法"); } @Override public void setEnvironment(Environment environment) { System.out.println("4 我是 EnvironmentAware 的 setEnvironment 方法"); } @Override public void setEmbeddedValueResolver(StringValueResolver stringValueResolver) { System.out.println("5 我是 EmbeddedValueResolverAware 的 setEmbeddedValueResolver 方法"); } @Override public void setResourceLoader(ResourceLoader resourceLoader) { System.out.println("6 我是 ResourceLoaderAware 的 setResourceLoader 方法"); } @Override public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { System.out.println("7 我是 ApplicationEventPublisherAware 的 setApplicationEventPublisher 方法"); } @Override public void setMessageSource(MessageSource messageSource) { System.out.println("8 我是 MessageSourceAware 的 setMessageSource 方法"); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { System.out.println("9 我是 ApplicationContextAware 的 setApplicationContext 方法"); } @Override public void setServletContext(ServletContext servletContext) { System.out.println("10 我是 ServletContextAware 的 setServletContext 方法"); } @Override public void setLoadTimeWeaver(LoadTimeWeaver loadTimeWeaver) { //LoadTimeWeaver 简称LTW,LTW是AOP的一种实现方式,此方法是为了获取Aop织入的对象,使用的织入方式是:类加载期织入, // 一般的aop都是运行期织入,就是在运行的时候才进行织入切面方法,但是LTW是在类加载前就被织入了,也就是class文件在jvm加载之前进行织入切面方法 // 只有在使用 @EnableLoadTimeWeaving 或者存在 LoadTimeWeaver 实现的 Bean 时才会调用,顺序也很靠后 System.out.println("11 我是 LoadTimeWeaverAware 的 setLoadTimeWeaver 方法"); } @Override public void setImportMetadata(AnnotationMetadata annotationMetadata) { //只有被其他配置类 @Import(XX.class) 时才会调用,这个调用对 XX.class 中的所有 @Bean 来说顺序是第 1 的。 System.out.println("12 我是 ImportAware 的 setImportMetadata 方法"); } |