• spring bean的生命周期


    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注解");
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                
            }
        }
        
    }
  • 相关阅读:
    asp.net core过滤器记录响应对象
    ef core实现无感知软删除
    Egret资源跨域问题
    ASP.Net Core中使用jquery-ajax-unobtrusive替换Ajax.BeginForm
    把.Net开发环境迁移到Linux上去
    Mysql8.0升级后,Navicat连接报错caching_sha2_password 问题
    改MySQL的编码方式,解决jdbc MySQL中文乱码问题
    怡红公子专属网址导航
    html以前没有学到的标签
    有哪些质量上乘的程序员必关注的网站或论坛
  • 原文地址:https://www.cnblogs.com/linhongwenBlog/p/14378760.html
Copyright © 2020-2023  润新知