企业网站推广的重要性,一个人看手机在线视频,模版 网站需要多少钱,湛江免费网站制作1.生命周期
Spring应用中容器管理了我们每一个bean的生命周期#xff0c;为了保证系统的可扩展性#xff0c;同时为用户提供自定义的能力#xff0c;Spring提供了大量的扩展点。完整的Spring生命周期如下图所示#xff0c;绿色背景的节点是ApplictionContext生命周期特有的…1.生命周期
Spring应用中容器管理了我们每一个bean的生命周期为了保证系统的可扩展性同时为用户提供自定义的能力Spring提供了大量的扩展点。完整的Spring生命周期如下图所示绿色背景的节点是ApplictionContext生命周期特有的节点单纯从生命周期上来看BeanFactory的生命周期和ApplicationContext的生命周期差异不大不单独论述。
ApplicationContext和BeanFactory还有一个值得一提的差异是ApplicationContext会自动查找容器内的BeanFactoryPostProcessor、InstantiationAwareBeanPostProcessor、BeanPostProcessor自动引用到上下文中BeanFactory必须自己手动调用addBeanPostProcessor。 我把整个Bean的生命周期分为5个阶段如图最左侧的大括号所示分别是: 配置解析、实例化、依赖注入、初始化、销毁。下面我们会依次查看它能做什么Spring什么特性依赖于它以及我们的开发中能怎么利用这个特性。
2. 配置解析 正常生命周期中我们不直接参与配置解析通过BeanFactoryPostProcessor的postProcessBeanFactory回调我们能拿到ConfigurableListableBeanFactory通过beanFactory.getBeanDefinition(beanName)对BeanDefinition对象做读取和设置。在Spring内部有两种使用场景
1. 做准备工作
在Bean实例化前做准备工作。这类对象以CustomAutowireConfigurer、CustomEditorConfigurer为代表CustomAutowireConfigurer继承BeanFactoryPostProcessor类覆写postProcessBeanFactory会从当前的BeanFactory中查找QualifierAnnotationAutowireCandidateResolver实例并将customQualifierTypes里的注解类添加到QualifierAnnotationAutowireCandidateResolver中。
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {if (this.customQualifierTypes ! null) {...DefaultListableBeanFactory dlbf (DefaultListableBeanFactory)beanFactory;...QualifierAnnotationAutowireCandidateResolver resolver (QualifierAnnotationAutowireCandidateResolver)dlbf.getAutowireCandidateResolver();Iterator var4 this.customQualifierTypes.iterator();while(var4.hasNext()) {...resolver.addQualifierType(customType);}}
}
2. 改Bean定义
在实例化前修改BeanDefinition中的配置中比如替换占位符。这类对象以PropertyPlaceholderConfigurer为代表PropertyPlaceholderConfigurer间接继承了BeanFactoryPostProcessor核心逻辑都在doProcessProperties中这里的BeanDefinitionVisitor的作用就是使用valueResolver将BeanDefinition中的占位符替换为配置文件中的值。
protected void doProcessProperties(ConfigurableListableBeanFactory beanFactoryToProcess, StringValueResolver valueResolver) {BeanDefinitionVisitor visitor new BeanDefinitionVisitor(valueResolver);...for(int var7 0; var7 var6; var7) {...if (!curName.equals(this.beanName) || !beanFactoryToProcess.equals(this.beanFactory)) {BeanDefinition bd beanFactoryToProcess.getBeanDefinition(curName);...visitor.visitBeanDefinition(bd);}}...
}
看代码得到的额外收获是BeanDefinitionVisitor的使用是典型的Visitor模式当数据结构稳定而操作不稳定时用Visitor模式能隔易变的逻辑独立在稳定的数据结构之外。
3. 实例化 3.1 postProcessBeforeInstantiation
这里将InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation做为实例化的一部分因为postProcessBeforeInstantiation返回非null的情况下将会跳过构造函数实例化直接用postProcessBeforeInstantiation返回的对象做为bean实例。比如下面的例子通过BeanFactory.getBean(globalProduct)返回的就是我们创建的id5678的Product对象并且跳过InstantiationAwareBeanPostProcessor的后两个回调函数。
public class ProductInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {public Object postProcessBeforeInstantiation(Class? beanClass, String beanName) throws BeansException {if (globalProduct.equals(beanName)) {System.out.println(postProcessBeforeInstantiation-----beanClass: beanClass.getName() ,beanName: beanName);Product product new Product();product.setId(5678L);product.setStaticScore(2.333F);product.setRelationScore(3.444F);product.setCategoryId(8765);return product;}return null;}...
}
3.2 构造函数
这里的构造函数实例化不仅限于实际Java类的构造函数还可以是FactoryBean.getObject或者使用Spring的factory-bean、factory-method创建Bean的过程。
4. 依赖注入 4.1 InstantiationAwareBeanPostProcessor
通过InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation修改bean对象完成属性注入。
Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {if (globalProduct.equals(beanName)) {System.out.println(postProcessAfterInstantiation-----bean: bean ,beanName: beanName);PropertyDescriptor prop BeanUtils.getPropertyDescriptor(bean.getClass(),id);Method writer prop.getWriteMethod();writer.invoke(bean,Long.valueOf(2222)); // 将globaleProduct bean的id改为2222}return true;
}
此外通过postProcessProperties回调直接修改现有的PropertyValues或者往PropertyValues里新增PropertyValue即可
Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {if (globalProduct.equals(beanName)) {System.out.println(postProcessProperties-----pvs: pvs ,bean: bean ,beanName: beanName);MutablePropertyValues mpvs (MutablePropertyValues) pvs;mpvs.addPropertyValue(id,3333); // 将globaleProduct bean的id改为3333return mpvs;}return pvs;
}
4.2 依赖注入
普通的setter方法注入、Autowired基于方法入参、字段的注入。
4.3 回调接口
包括BeanNameAware、BeanFactoryAware、ApplicationContextAware这3个接口都逻辑都很简单提供一个set方法容器将对于的对象通过set方法入参传递给bean实例。
private String beanName;
Override
public void setBeanName(String name) {this.beanName name;
}private BeanFactory beanFactory;
Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {this.beanFactory beanFactory;
}private ApplicationContext applicationContext;
Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext applicationContext;
}
5.初始化 5.1 BeanPostProcessor
BeanPostProcessor有两个方法postProcessBeforeInitialization在Bean调用InitializingBean、init-method等初始化方法前调用
Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if (globalProduct.equals(beanName)) {System.out.println(postProcessBeforeInitialization bean: bean);}return bean;
}
在Bean调用InitializingBean、init-method等初始化方法后调用
Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (globalProduct.equals(beanName)) {System.out.println(postProcessAfterInitialization bean: bean);}return bean;
}
5.2 InitializingBean
需要Bean对象自己实现InitializingBean接口的afterPropertiesSet方法这里我们只是简单的打印。
public class Product implements InitializingBean {Overridepublic void afterPropertiesSet() throws Exception {System.out.println(Product.afterPropertiesSet);}
}
5.3 init-method、PostConstruct
init-method和PostConstruct作用和InitializingBean的afterPropertiesSet方法相同用于做初始化动作。好处是我们的Bean不再需要继续一个Spring接口而是通过配置或注解触发初始化方法调用。
通过配置init-method
Bean(initMethod afterPropertiesSet)
public Product globalProduct() {Product product new Product();...return product;
}
通过PostConstruct注解
PostConstruct
public void afterPropertiesSet() throws Exception {System.out.println(Product.afterPropertiesSet);
}
6. 销毁 6.1 DisposableBean
需要Bean对象实现DisposableBean的destroy方法这里我们只是简单的打印
public class Product implements DisposableBean{public void destroy() throws Exception {System.out.println(Product.destroy);}
}
6.2 destroy-method、PreDestroy
destroy-method和PreDestroy的作用和DisposableBean的destroy方法作用一致好处是不需要Bean实现Spring的接口。
通过destroy-method
Bean(destroyMethod destroy)
public Product globalProduct() {Product product new Product();...return product;
}
通过PreDestroy
PreDestroy
public void destroy() throws Exception {System.out.println(Product.destroy);
}