Spring再次学习(4)
2019-08-16 12:16:59来源:博客园 阅读 ()
Spring再次学习(4)
时隔一年多,在掌握了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; }
原文链接:https://www.cnblogs.com/xuyiqing/p/11307820.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:方法重载
- Spring系列.ApplicationContext接口 2020-06-11
- springboot2配置JavaMelody与springMVC配置JavaMelody 2020-06-11
- 学习Java 8 Stream Api (4) - Stream 终端操作之 collect 2020-06-11
- java学习之第一天 2020-06-11
- 给你一份超详细 Spring Boot 知识清单 2020-06-11
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash