首页>>后端>>Spring->简述Spring的常用接口及生命周期

简述Spring的常用接口及生命周期

时间:2023-11-29 本站 点击:0

ApplicationContextAware

当一个类实现了这个接口(ApplicationContextAware)之后,这个类就可以方便获得ApplicationContext中的所有bean。换句话说,就是这个类可以直接获取spring配置文件中,所有有引用到的bean对象。

如果读过源码,就会发现BeanFactory中其实保存了Spring Bean容器中的属性,但是BeanFactory是一个接口且不对外暴露,真正暴露的其实是ApplicationContext,应为ApplicationContext中有一个getAutowireCapableBeanFactory方法,返回AutowireCapableBeanFactory接口,而AutowireCapableBeanFactory接口继承了BeanFactory接口。

@ServicepublicclassExcelOutYardManagerimplementsApplicationContextAware{Map<String,IExcelOutYard>excelOutYardMap;privateMap<String,IExcelOutYard>getExcelOutYard(){if(excelOutYardMap==null){excelOutYardMap=newHashMap<String,IExcelOutYard>();}returnexcelOutYardMap;}publicIExcelOutYardgetImpleService(StringmessageType){returnexcelOutYardMap.get(messageType);}@OverridepublicvoidsetApplicationContext(ApplicationContextapplicationContext)throwsBeansException{Map<String,IExcelOutYard>beansOfType=applicationContext.getBeansOfType(IExcelOutYard.class);this.getExcelOutYard();for(IExcelOutYardiExcelOutYard:beansOfType.values()){excelOutYardMap.put(iExcelOutYard.messageType(),iExcelOutYard);}}}

InitializingBean接口

InitializingBean接口为bean提供了初始化方法的方式,只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候会执行该方法。一般用这个接口在Spring初始化bean之后做一些初始化操作。

这个特性比较多的运用在应用启动的时候设定自动执行的方法,比如应用启动时,从数据库查询出数据,放入对象

@ServicepublicclassEdiInitializingServiceimplementsInitializingBean{@OverridepublicvoidafterPropertiesSet()throwsException{-----

BeanPostProcessor接口

在Spring容器中完成bean实例化、配置以及其它初始化方法前后要添加一些特殊的处理逻辑。需要定义一个或多个BeanPostProcessor接口实现类,然后注册到SpringIOC容器中。

下面这个例子就是根据自定义注解拦截要注入的接口实现类,运用java反射和代理的知识点来进行有效的实现类注入。

publicinterfaceHelloService{publicvoidsayHello();}
@ServicepublicclassHelloServiceImpl1implementsHelloService{@OverridepublicvoidsayHello(){System.out.println("你好我是HelloServiceImpl1");}}
@ServicepublicclassHelloServiceImpl2implementsHelloService{@OverridepublicvoidsayHello(){System.out.println("你好我是HelloServiceImpl2");}}
@Target({ElementType.FIELD})@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic@interfaceRountingInjected{Stringvalue()default"helloServiceImpl1";}
@ComponentpublicclassHelloServiceInjectProcessorimplementsBeanPostProcessor{@AutowiredprivateApplicationContextapplicationContext;@OverridepublicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName)throwsBeansException{returnbean;}@OverridepublicObjectpostProcessAfterInitialization(Objectbean,StringbeanName)throwsBeansException{Class<?>targetCls=bean.getClass();Field[]targetFld=targetCls.getDeclaredFields();for(Fieldfield:targetFld){//找到制定目标的注解类if(field.isAnnotationPresent(RountingInjected.class)){if(!field.getType().isInterface()){thrownewBeanCreationException("RoutingInjectedfieldmustbedeclaredasaninterface:"+field.getName()+"@Class"+targetCls.getName());}try{this.handleRoutingInjected(field,bean,field.getType());}catch(IllegalAccessExceptione){e.printStackTrace();}}}returnbean;}/***@paramfield*@parambean*@paramtype*@throwsIllegalAccessException*/privatevoidhandleRoutingInjected(Fieldfield,Objectbean,Classtype)throwsIllegalAccessException{Map<String,Object>candidates=this.applicationContext.getBeansOfType(type);field.setAccessible(true);if(candidates.size()==1){field.set(bean,candidates.values().iterator().next());}elseif(candidates.size()==2){StringinjectVal=field.getAnnotation(RountingInjected.class).value();Objectproxy=RoutingBeanProxyFactory.createProxy(injectVal,type,candidates);field.set(bean,proxy);}else{thrownewIllegalArgumentException("Findmorethan2beansfortype:"+type);}}}
publicclassRoutingBeanProxyFactory{privatefinalstaticStringDEFAULT_BEAN_NAME="helloServiceImpl1";publicstaticObjectcreateProxy(Stringname,Classtype,Map<String,Object>candidates){ProxyFactoryproxyFactory=newProxyFactory();proxyFactory.setInterfaces(type);proxyFactory.addAdvice(newVersionRoutingMethodInterceptor(name,candidates));returnproxyFactory.getProxy();}staticclassVersionRoutingMethodInterceptorimplementsMethodInterceptor{privateObjecttargetObject;publicVersionRoutingMethodInterceptor(Stringname,Map<String,Object>beans){this.targetObject=beans.get(name);if(this.targetObject==null){this.targetObject=beans.get(DEFAULT_BEAN_NAME);}}@OverridepublicObjectinvoke(MethodInvocationinvocation)throwsThrowable{returninvocation.getMethod().invoke(this.targetObject,invocation.getArguments());}}}
@ComponentpublicclassHelloServiceTest{@RountingInjected(value="helloServiceImpl2")privateHelloServicehelloService;publicvoidtestSayHello(){helloService.sayHello();}publicstaticvoidmain(String[]args){AnnotationConfigApplicationContextapplicationContext=newAnnotationConfigApplicationContext("colin.spring.basic.advanced.bbp");HelloServiceTesthelloServiceTest=applicationContext.getBean(HelloServiceTest.class);helloServiceTest.testSayHello();}}

DisposableBean接口

Spring bean被销毁时调用,这个使用较少,但也是生命周期的一部分

Spring生命周期图

结语

如果和spring生命周期图对照,那么可以看到,每一个接口的实现就是spring生命周期的一部分,这些接口实际上也体现了Spring框架的灵活性,理解这些接口对spring框架的使用有极大的帮助。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/Spring/294.html