spring bean的生命周期
ApplicationContextAware接口
当一个类实现了这个接口之后,这个类就可以方便地获得ApplicationContext对象
Spring发现某个Bean实现了ApplicationContextAware接口,Spring容器会在创建该Bean之后,自动调用该Bean的setApplicationContextAware()方法,调用该方法时,会将容器本身ApplicationContext对象作为参数传给该方法。
InitializingBean 接口
当一个类实现这个接口之后,Spring启动时,初始化Bean时,若该Bean实现InitializingBean接口,则会自动调用afterPropertiesSet()方法,完成一些用户自定义的初始化操作。
全生命周期样例:
package com.check; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.BeansException; import org.springframework.beans.factory.*; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Service; /** * @author lin.hongwen * @date 2021-02-05 * @Description */ @Service public class LhwTest implements ApplicationContextAware,InitializingBean,BeanNameAware,BeanFactoryAware,BeanPostProcessor,DisposableBean { private static final Logger LOG = LogManager.getLogger(LhwTest.class); private ApplicationContext applicationContext; @Override public void setBeanName(String var1) { //顺序1 获取bean的名字。值是lhwTest String beanName = var1; LOG.info("setBeanName=="+beanName); } @Override public void setBeanFactory(BeanFactory var1) { //顺序2 获取bean示例工厂 BeanFactory beanFactory = var1; LOG.info("setBeanFactory=="+beanFactory); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { //顺序3 获取上下文 this.applicationContext = applicationContext; LOG.info("setApplicationContext=="+applicationContext); } @Override public void afterPropertiesSet() { // 顺序4 已经完成了所有bean基础信息的封装 // 这时候可以获取spring上下文,获取所有bean的信息 String names[]=applicationContext.getBeanDefinitionNames(); LOG.info("afterPropertiesSet"); } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) { // 顺序5 对每个已经封装好基础信息的bean进行 准备开始实例化 LOG.info("postProcessBeforeInitialization.bean=="+bean); LOG.info("postProcessBeforeInitialization.beanName=="+beanName); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) { // 顺序5 已经完成bean的实例化 LOG.info("postProcessAfterInitialization.bean=="+bean); LOG.info("postProcessAfterInitialization.beanName=="+beanName); return bean; } @Override public void destroy() {
//不知道有啥用 LOG.info("destroy"); } }
样例:
e.g获取spring上下文,并根据上下文内容。过滤method,判断返回值是否符合要求
package com.lhw import java.lang.reflect.Method; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Controller; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import io.swagger.annotations.Api; @Service public class StandardCheck implements ApplicationContextAware,InitializingBean { private static final Logger LOG = LogManager.getLogger(StandardCheck.class); private ApplicationContext applicationContext; //不用检查的方法 @Value("${uncheckLogMethod}") private String uncheckLogMethod; //是否开启检查 @Value("${standardCheckFlag}") private String standardCheckFlag; private String[]uncheckLogMethods; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { //获取上下文 this.applicationContext = applicationContext; } @Override public void afterPropertiesSet() throws Exception { //在spring初始化后调用此方法 if(LOG.isInfoEnabled()) { LOG.info("standardCheckFlag={}",standardCheckFlag); LOG.info("uncheckLogMethod={}",uncheckLogMethod); } if("true".equals(standardCheckFlag)) { if(StringUtils.isNotBlank(uncheckLogMethod)&&!"${uncheckLogMethod}".equals(uncheckLogMethod)) { uncheckLogMethods=uncheckLogMethod.split(","); } loadApiFromSpringBeans(); } } private void loadApiFromSpringBeans(){ //获取spring上下文 String names[]=applicationContext.getBeanDefinitionNames(); for(String name:names){ //获取这个类 Class<?>type = applicationContext.getType(name); //获取类的相对路径名称 String className = type.getName(); if(StringUtils.isNotBlank(className)) { if(className.startsWith("com.controller")) { if("com.BaseController".equals(className)) { continue; } //获取父类,要求所有类必须继承com.BaseController Class<?>superClass = type.getSuperclass(); if(superClass != null) { if(!"com.BaseController".equals(superClass.getName())) { throw new RuntimeException(type.getSuperclass().getName()+"["+className+"]必须继承com.BaseController"); } } //获取注解,要求所有类必须有@Controller、@RestController、@Api注解 if(type.getAnnotation(Controller.class)==null&&type.getAnnotation(RestController.class)==null) { throw new RuntimeException("["+className+"]必须有Controller或RestController的注解"); } if(type.getAnnotation(Api.class)==null) { throw new RuntimeException("["+className+"]必须有io.swagger.annotations.Api的注解"); } //获取类下的已声明的方法 Method methods[] = type.getDeclaredMethods(); if(methods != null){ boolean checkFlag = true; for(Method method:methods){ //获取方法的返回值 Class<?>returnType = method.getReturnType(); if(method.getAnnotation(RequestMapping.class)!=null) { //带有@RequestMapping的注解才需要检查 //判断方法的返回值是否合规 if(!"com.ResultData".equals(returnType.getName())) { throw new RuntimeException("["+className+"."+method.getName()+"]必须返回com.ResultData"); } //判断这个方法是否需要检查其他内容 String methodFullName = className+"."+method.getName(); if(uncheckLogMethods!=null) { for(String um:uncheckLogMethods) { if(methodFullName.equals(um)) { checkFlag = false; break; } } } if(checkFlag) { //需要检查,检查该方法所需要的其他注解 OperationLog operLog = method.getAnnotation(OperationLog.class); if(operLog==null) { throw new RuntimeException("["+className+"."+method.getName()+"]必须增加OperationLog注解"); } } } } } } } } } }