Spring再次学习
Posted xuyiqing
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring再次学习相关的知识,希望对你有一定的参考价值。
时隔一年多,在掌握了Spring、SpringBoot、SpringCloud之后
我再次回头,重新学习Spring框架
Bean的生命周期学习:
在传统的XML配置中,可以这样自定义初始化和销毁方法:
init-method="" destroy-method=""
注解方式的简单使用:
@Configuration public class LifeCircleConfig @Bean(initMethod = "init",destroyMethod = "destroy") public Car car() return new Car();
public class Car public Car() System.out.println("Construct Car!"); public void init() System.out.println("Car init!"); public void destroy() System.out.println("Car destroy!");
public class LifeCircleTest private static AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(LifeCircleConfig.class); @Test public void test() applicationContext.close();
注意:要有close方法,否则不会打印Car销毁方法
打印如下:
Construct Car! Car init! Car destroy!
这里默认的是单实例Bean
如果是多实例的话,按照以上的测试代码是不会打印的,因为多实例情况下,在获取Bean的情况下才会创建对象
而且在多例情况下,只会调用初始化和构造方法,不会调用销毁方法
以上测试代码只完成了初始化IOC容器,所以什么都不打印
实现Spring中接口方式:这时候不需要在@Bean中进行配置
public class Car implements InitializingBean, DisposableBean public Car() System.out.println("Construct Car!"); public void afterPropertiesSet() throws Exception System.out.println("Car init!"); public void destroy() System.out.println("Car destroy!");
使用Java原生注解:
public class Car public Car() System.out.println("Construct Car!"); @PostConstruct public void init() System.out.println("Car init!"); @PreDestroy public void destroy() System.out.println("Car destroy!");
使用Spring中Bean的后置处理器:
@Component public class MyBeanPostProcessor implements BeanPostProcessor /** * 初始化前调用 */ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException System.out.println("postProcessBeforeInitialization " + bean + " " + beanName); return bean; /** * 初始化后调用 */ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException System.out.println("postProcessAfterInitialization " + bean + " " + beanName); return bean;
@Configuration @ComponentScan("org.dreamtech.bean") public class LifeCircleConfig @Bean public Car car() return new Car();
测试后部分打印如下:
Construct Car!
postProcessBeforeInitialization org.dreamtech.bean.Car@2d9d4f9d car
postProcessAfterInitialization org.dreamtech.bean.Car@2d9d4f9d car
BeanPostProcessor原理:
查看这一段源码:
initializeBean(beanName, exposedObject, mbd)方法中:
Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); try invokeInitMethods(beanName, wrappedBean, mbd); catch (Throwable ex) throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); if (mbd == null || !mbd.isSynthetic()) wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
在invokeInitMethods初始化方法之前
调用了applyBeanPostProcessorsBeforeInitialization,也就是调用了所有PostProcessor的Before方法
在invokeInitMethods初始化方法之后
调用了applyBeanPostProcessorsAfterInitialization,也就是调用了所有PostProcessor的After方法
进入applyBeanPostProcessorsBeforeInitialization方法查看源码:
遍历所有的Processor,一旦返回null,就会跳出循环
@Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) result = beanProcessor.postProcessBeforeInitialization(result, beanName); if (result == null) return result; return result;
在initializeBean方法之前,调用的是populateBean方法
作用:给属性赋值
// Initialize the bean instance. Object exposedObject = bean; try populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) exposedObject = initializeBean(beanName, exposedObject, mbd);
所以:BeanPostProcessor是在Bean赋值之后,初始化的过程前后执行的
BeanPostProcessor在Spring底层的使用:
获取IOC容器的接口:
public interface ApplicationContextAware extends Aware void setApplicationContext(ApplicationContext var1) throws BeansException;
而它就是基于BeanPostProcessor的,代码过长就不截取了
class ApplicationContextAwareProcessor implements BeanPostProcessor
或者是参数校验:也使用到了BeanPostProcessor
public class BeanValidationPostProcessor implements BeanPostProcessor, InitializingBean
部分代码如下:
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException if (!this.afterInitialization) this.doValidate(bean); return bean; public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException if (this.afterInitialization) this.doValidate(bean); return bean;
以上是关于Spring再次学习的主要内容,如果未能解决你的问题,请参考以下文章