BeanPostProcessor接口作用:
如果我们想在Spring容器中完成bean实例化、配置以及其他初始化方法前后要添加一些自己逻辑处理。我们需要定义一个或多个BeanPostProcessor接口实现类,然后注册到SpringIoC容器中。
packagecom.test.spring; importorg.springframework.beans.BeansException; importorg.springframework.beans.factory.config.BeanPostProcessor; /** *bean后置处理器 *@authorzss * */ publicclassPostProcessorimplementsBeanPostProcessor{ @Override publicObjectpostProcessBeforeInitialization(Objectbean, StringbeanName)throwsBeansException{ if("narCodeService".equals(beanName)){//过滤掉bean实例ID为narCodeService returnbean; } System.out.println("后置处理器处理bean=【"+beanName+"】开始"); try{ Thread.sleep(1000); }catch(InterruptedExceptione){ e.printStackTrace(); } returnbean; } @Override publicObjectpostProcessAfterInitialization(Objectbean, StringbeanName)throwsBeansException{ if("narCodeService".equals(beanName)){ returnbean; } System.out.println("后置处理器处理bean=【"+beanName+"】完毕!"); try{ Thread.sleep(1000); }catch(InterruptedExceptione){ e.printStackTrace(); } returnbean; } } 注意:接口中两个方法不能返回null,如果返回null那么在后续初始化方法将报空指针异常或者通过getBean()方法获取不到bena实例对象 因为后置处理器从SpringIoC容器中取出bean实例对象没有再次放回IoC容器中将Spring的后置处理器PostProcessor配置到Spring配置文件中
<?xmlversion="1.0"encoding="UTF-8"?> <beansxmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--定义一个bean--> <beanid="narCodeService"class="com.test.service.impl.NarCodeServiceImpl"> </bean> <beanid="beanLifecycle"class="com.test.spring.BeanLifecycle"init-method="init"destroy-method="close"> <propertyname="name"value="张三"></property> <propertyname="sex"value="男"></property> </bean> <!--Spring后置处理器--> <beanid="postProcessor"class="com.test.spring.PostProcessor"/> </beans>BeanPostProcessorAPI:
publicinterfaceBeanPostProcessor{ /** *ApplythisBeanPostProcessortothegivennewbeaninstance<i>before</i>anybean *initializationcallbacks(likeInitializingBeans{@codeafterPropertiesSet} *oracustominit-method).Thebeanwillalreadybepopulatedwithpropertyvalues. */ //实例化、依赖注入完毕,在调用显示的初始化之前完成一些定制的初始化任务 ObjectpostProcessBeforeInitialization(Objectbean,StringbeanName)throwsBeansException; /** *ApplythisBeanPostProcessortothegivennewbeaninstance<i>after</i>anybean *initializationcallbacks(likeInitializingBeans{@codeafterPropertiesSet} *oracustominit-method).Thebeanwillalreadybepopulatedwithpropertyvalues. */ //实例化、依赖注入、初始化完毕时执行 ObjectpostProcessAfterInitialization(Objectbean,StringbeanName)throwsBeansException; } 由API可以看出: 1:后置处理器的postProcessorBeforeInitailization方法是在bean实例化,依赖注入之后及自定义初始化方法(例如:配置文件中bean标签添加init-method属性指定Java类中初始化方法、 @PostConstruct注解指定初始化方法,Java类实现InitailztingBean接口)之前调用 2:后置处理器的postProcessorAfterInitailization方法是在bean实例化、依赖注入及自定义初始化方法之后调用 注意: 1.BeanFactory和ApplicationContext两个容器对待bean的后置处理器稍微有些不同。ApplicationContext容器会自动检测Spring配置文件中那些bean所对应的Java类实现了BeanPostProcessor 接口,并自动把它们注册为后置处理器。在创建bean过程中调用它们,所以部署一个后置处理器跟普通的bean没有什么太大区别。2.BeanFactory容器注册bean后置处理器时必须通过代码显示的注册,在IoC容器继承体系中的ConfigurableBeanFactory接口中定义了注册方法
/** *AddanewBeanPostProcessorthatwillgetappliedtobeanscreated *bythisfactory.Tobeinvokedduringfactoryconfiguration. *<p>Note:Post-processorssubmittedherewillbeappliedintheorderof *registration;anyorderingsemanticsexpressedthroughimplementingthe *{@linkorg.springframework.core.Ordered}interfacewillbeignored.Note *thatautodetectedpost-processors(e.g.asbeansinanApplicationContext) *willalwaysbeappliedafterprogrammaticallyregisteredones. *@parambeanPostProcessorthepost-processortoregister */ voidaddBeanPostProcessor(BeanPostProcessorbeanPostProcessor);Spring如何调用多个BeanPostProcessor实现类:
我们可以在Spring配置文件中添加多个BeanPostProcessor(后置处理器)接口实现类,在默认情况下Spring容器会根据后置处理器的定义顺序来依次调用。
Spring配置文件:
<?xmlversion="1.0"encoding="UTF-8"?> <beansxmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--bean定义--> <beanid="narCodeService"class="com.test.service.impl.NarCodeServiceImpl"> </bean> <beanid="postProcessor"class="com.test.spring.PostProcessor"/> <beanid="postProcessorB"class="com.test.spring.PostProcessorB"/> </beans>BeanPostProcessor实现类:
packagecom.test.spring; importorg.springframework.beans.BeansException; importorg.springframework.beans.factory.config.BeanPostProcessor; /** *bean后置处理器 *@authorzss * */ publicclassPostProcessorimplementsBeanPostProcessor{ @Override publicObjectpostProcessBeforeInitialization(Objectbean, StringbeanName)throwsBeansException{ System.out.println("后置处理器处理bean=【"+beanName+"】开始"); try{ Thread.sleep(1000); }catch(InterruptedExceptione){ e.printStackTrace(); } returnbean; } @Override publicObjectpostProcessAfterInitialization(Objectbean, StringbeanName)throwsBeansException{ System.out.println("后置处理器处理bean=【"+beanName+"】完毕!"); try{ Thread.sleep(1000); }catch(InterruptedExceptione){ e.printStackTrace(); } returnbean; } } ---------------------------------------------------------------------------------------------------------------------------------------- packagecom.test.spring; importorg.springframework.beans.BeansException; importorg.springframework.beans.factory.config.BeanPostProcessor; publicclassPostProcessorBimplementsBeanPostProcessor{ @Override publicObjectpostProcessBeforeInitialization(Objectbean, StringbeanName)throwsBeansException{ System.out.println("后置处理器开始调用了"); try{ Thread.sleep(1000); }catch(InterruptedExceptione){ e.printStackTrace(); } returnbean; } @Override publicObjectpostProcessAfterInitialization(Objectbean, StringbeanName)throwsBeansException{ System.out.println("后置处理器调用结束了"); try{ Thread.sleep(1000); }catch(InterruptedExceptione){ e.printStackTrace(); } returnbean; } }测试:
packagecom.test.spring; importorg.junit.Before; importorg.junit.Test; importorg.springframework.context.support.AbstractApplicationContext; importorg.springframework.context.support.ClassPathXmlApplicationContext; publicclassT{ AbstractApplicationContextapplicationcontext=null; @Before publicvoidbefore(){ System.out.println("》》》SpringApplicationContext容器开始初始化了......"); applicationcontext=newClassPathXmlApplicationContext(newString[]{"test1-service.xml"}); System.out.println("》》》SpringApplicationContext容器初始化完毕了......"); } @Test publicvoidtest(){ applicationcontext.registerShutdownHook(); } }测试结果:
》》》SpringApplicationContext容器开始初始化了...... 2017-03-1910:50:29INFO:ClassPathXmlApplicationContext-Refreshingorg.springframework.context.support.ClassPathXmlApplicationContext@18c92ff9:startupdate[SunMar1910:50:29CST2017];rootofcontexthierarchy 2017-03-1910:50:29INFO:XmlBeanDefinitionReader-LoadingXMLbeandefinitionsfromclasspathresource[test1-service.xml] 后置处理器处理bean=【narCodeService】开始 后置处理器开始调用了 后置处理器处理bean=【narCodeService】完毕! 后置处理器调用结束了 》》》SpringApplicationContext容器初始化完毕了...... 2017-03-1910:50:34INFO:ClassPathXmlApplicationContext-Closingorg.springframework.context.support.ClassPathXmlApplicationContext@18c92ff9:startupdate[SunMar1910:50:29CST2017];rootofcontexthierarchy在Spring机制中可以指定后置处理器调用顺序,通过让BeanPostProcessor接口实现类实现Ordered接口getOrder方法,该方法返回一整数,默认值为0,优先级最高,值越大优先级越低
例如:
packagecom.test.spring; importorg.springframework.beans.BeansException; importorg.springframework.beans.factory.config.BeanPostProcessor; importorg.springframework.core.Ordered; /** *bean后置处理器 *@authorzss * */ publicclassPostProcessorimplementsBeanPostProcessor,Ordered{ @Override publicObjectpostProcessBeforeInitialization(Objectbean, StringbeanName)throwsBeansException{ System.out.println("后置处理器处理bean=【"+beanName+"】开始"); try{ Thread.sleep(1000); }catch(InterruptedExceptione){ e.printStackTrace(); } returnbean; } @Override publicObjectpostProcessAfterInitialization(Objectbean, StringbeanName)throwsBeansException{ System.out.println("后置处理器处理bean=【"+beanName+"】完毕!"); try{ Thread.sleep(1000); }catch(InterruptedExceptione){ e.printStackTrace(); } returnbean; } @Override publicintgetOrder(){ return1; } } ---------------------------------------------------------------------------- packagecom.test.spring; importorg.springframework.beans.BeansException; importorg.springframework.beans.factory.config.BeanPostProcessor; importorg.springframework.core.Ordered; publicclassPostProcessorBimplementsBeanPostProcessor,Ordered{ @Override publicObjectpostProcessBeforeInitialization(Objectbean, StringbeanName)throwsBeansException{ System.out.println("后置处理器开始调用了"); try{ Thread.sleep(1000); }catch(InterruptedExceptione){ e.printStackTrace(); } returnbean; } @Override publicObjectpostProcessAfterInitialization(Objectbean, StringbeanName)throwsBeansException{ System.out.println("后置处理器调用结束了"); try{ Thread.sleep(1000); }catch(InterruptedExceptione){ e.printStackTrace(); } returnbean; } @Override publicintgetOrder(){ return0; } }测试结果:
》》》SpringApplicationContext容器开始初始化了......
2017-03-1911:04:10INFO:ClassPathXmlApplicationContext-Refreshingorg.springframework.context.support.ClassPathXmlApplicationContext@18c92ff9:startupdate[SunMar1911:04:10CST2017];rootofcontexthierarchy
2017-03-1911:04:10INFO:XmlBeanDefinitionReader-LoadingXMLbeandefinitionsfromclasspathresource[test1-service.xml]
后置处理器开始调用了
后置处理器处理bean=【narCodeService】开始
后置处理器调用结束了
后置处理器处理bean=【narCodeService】完毕!
》》》SpringApplicationContext容器初始化完毕了......
2017-03-1911:04:14INFO:ClassPathXmlApplicationContext-Closingorg.springframework.context.support.ClassPathXmlApplicationContext@18c92ff9:startupdate[SunMar1911:04:10CST2017];rootofcontexthierarchy本文内容总结:
原文链接:https://www.cnblogs.com/sishang/p/6576665.html