seo教育,深圳网站seo 乐云践新,域名访问网站的知识,客户关系管理系统源码spring中bean的生命周期
上一个小节梳理了一下Spring Boot的依赖注入的基本知识#xff0c;今天来梳理一下spring中bean的生命周期。 下面#xff0c;让我们一起看看bean在IOC容器中是怎么被创建和销毁的。 bean的生命周期大致分为四个部分#xff1a; #mermaid-svg-GFXNEU…spring中bean的生命周期
上一个小节梳理了一下Spring Boot的依赖注入的基本知识今天来梳理一下spring中bean的生命周期。 下面让我们一起看看bean在IOC容器中是怎么被创建和销毁的。 bean的生命周期大致分为四个部分 #mermaid-svg-GFXNEURRe1fEVI1i {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GFXNEURRe1fEVI1i .error-icon{fill:#552222;}#mermaid-svg-GFXNEURRe1fEVI1i .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-GFXNEURRe1fEVI1i .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-GFXNEURRe1fEVI1i .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-GFXNEURRe1fEVI1i .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-GFXNEURRe1fEVI1i .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-GFXNEURRe1fEVI1i .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-GFXNEURRe1fEVI1i .marker{fill:#333333;stroke:#333333;}#mermaid-svg-GFXNEURRe1fEVI1i .marker.cross{stroke:#333333;}#mermaid-svg-GFXNEURRe1fEVI1i svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-GFXNEURRe1fEVI1i .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-GFXNEURRe1fEVI1i .cluster-label text{fill:#333;}#mermaid-svg-GFXNEURRe1fEVI1i .cluster-label span{color:#333;}#mermaid-svg-GFXNEURRe1fEVI1i .label text,#mermaid-svg-GFXNEURRe1fEVI1i span{fill:#333;color:#333;}#mermaid-svg-GFXNEURRe1fEVI1i .node rect,#mermaid-svg-GFXNEURRe1fEVI1i .node circle,#mermaid-svg-GFXNEURRe1fEVI1i .node ellipse,#mermaid-svg-GFXNEURRe1fEVI1i .node polygon,#mermaid-svg-GFXNEURRe1fEVI1i .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-GFXNEURRe1fEVI1i .node .label{text-align:center;}#mermaid-svg-GFXNEURRe1fEVI1i .node.clickable{cursor:pointer;}#mermaid-svg-GFXNEURRe1fEVI1i .arrowheadPath{fill:#333333;}#mermaid-svg-GFXNEURRe1fEVI1i .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-GFXNEURRe1fEVI1i .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-GFXNEURRe1fEVI1i .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-GFXNEURRe1fEVI1i .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-GFXNEURRe1fEVI1i .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-GFXNEURRe1fEVI1i .cluster text{fill:#333;}#mermaid-svg-GFXNEURRe1fEVI1i .cluster span{color:#333;}#mermaid-svg-GFXNEURRe1fEVI1i div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-GFXNEURRe1fEVI1i :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 定义 初始化 生存期 销毁 bean的定义和初始化
大致流程如下 Created with Raphaël 2.3.0 开始 资源定位(通过ComponentScan注解定义的扫描规则去寻找被Component、Controller、Service......等注解标记的类) 资源解析、并且将定义的信息保存起来 定义发布将bean的定义信息发布到ioc容器中 bean的初始化 结束 默认情况下spring会在启动时完成对bean的定义、发布以及初始化但是有时候我们并不想让spring在启动时就完成bean的初始化更想的是在我们用到它时才去完成初始化的动作最常见的就是循环依赖的场景了。 而解决这个问题就需要用到spring的延迟初始化的机制了。
spring的延迟初始化bean机制
可以使用2中方法使bean进行延迟初始化
ComponentScan注解的lazyInit属性
ComponentScan(basePackages {com.zzm.iocbeanlifeperiod},lazyInit true)设置该属性为true后对应的扫描规则下的bean都会进行延迟初始化
Lazy注解
该注解用于指定某一个依赖的bean进行延迟初始化用法如下 AutowiredLazyprivate Animal cat;bean的初始化生命周期的各个阶段
好了现在我们正式看看bean的生命周期的各个阶段如下图所示 这个流程介绍了bean从初始化到销毁的过程。 注意流程中的setApplicationContext方法有些特殊即使你定义了 ApplicationContextAware 接口但是有时候并不会调用这要根据你的 IoC器来决定。 我们知道 Spring IoC 容器最低的要求是实 BeanFactory 接口而不是ApplicationContext 接口 对于那些没有实现 Application Cont xt 接口的容器 在生命周期对应的 ApplicationContextAware 定义的方法也是不会被调用的只有实现了 Applic ationContext 接口的容器才会在生命周期调用 ApplicationContextAware 定义的 setApplicationContext 方法。 接下来让我们一起测试一下bean的生命周期。 首先创建一个类同时让它实现流程中的这些接口代码如下
Component
Slf4j
public class BeanLifePeriod implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean {Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {log.warn(【{}】调用了BeanFactoryAware的setBeanFactory,this.getClass().getSimpleName());}Overridepublic void setBeanName(String name) {log.warn(【{}】调用了BeanNameAware的setBeanName,this.getClass().getSimpleName());}Overridepublic void destroy() throws Exception {log.warn(【{}】调用了DisposableBean的destroy,this.getClass().getSimpleName());}PreDestroypublic void destroyMyself() {log.warn(【{}】调用了注解PreDestroy定义的自定义销毁方法,this.getClass().getSimpleName());}Overridepublic void afterPropertiesSet() throws Exception {log.warn(【{}】调用了InitializingBean的afterPropertiesSet,this.getClass().getSimpleName());}Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {log.warn(【{}】调用了ApplicationContextAware的setApplicationContext,this.getClass().getSimpleName());}PostConstructpublic void init(){log.warn(【{}】调用了注解PostConstruct定义的自定义初始化方法,this.getClass().getSimpleName());}
}因为BeanPostProcessor接口的方法是针对于所有的bean的所以我们这里单独创建一个类来实现它
Component
Slf4j
public class BeanPostProcessorExample implements BeanPostProcessor {Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {log.warn(BeanPostProcessor调用postProcessBeforeInitialization方法参数【{}{}】, bean.getClass().getSimpleName(), bean);return bean;}Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {log.warn(BeanPostProcessor调用postProcessAfterInitialization方法参数【{}{}】, bean.getClass().getSimpleName(), bean);return bean;}
}接下来创建ioc配置类和测试类
ComponentScan(basePackages {com.zzm.iocbeanlifeperiod})
Configuration
Slf4j
public class LifePeriodAppConfig {}public class IocBeanLifePeriod {public static void main(String[] args) throws InterruptedException {AnnotationConfigApplicationContext context new AnnotationConfigApplicationContext(LifePeriodAppConfig.class);context.close();}
}运行main方法可以看到如下日志 上面的流程可用于自定义的bean但是有时候bean不是我们自己定义的而是第三方的bean那怎么办呢 在小节全注解下的IOC中我们介绍了Bean注解它可以用来向容器发布第三方的bean所以通过它我们也可以自定义初始化和销毁的方法用法如下
ComponentScan(basePackages {com.zzm.iocbeanlifeperiod})
Configuration
Slf4j
public class LifePeriodAppConfig {Bean(value lifePeriodUser,initMethod init,destroyMethod destroy)public LifePeriodUser getUser(){return new LifePeriodUser().setId(3L).setUserName(Bean手动注入).setNote(Bean手动注入);}
}Data
Accessors(chain true)
Slf4j
public class LifePeriodUser {private Long id;private String userName;private String note;public void init(){log.warn(【{}】调用了自定义用户初始化方法,this.getClass().getSimpleName());}public void destroy(){log.warn(【{}】调用了自定义用户销毁方法,this.getClass().getSimpleName());}
}感兴趣的小伙伴可以自己尝试下今天就到这里了。。。。。