获取Spring容器里面所有的Bean

之前测试同事提过来一个问题,让帮忙统计项目中总共有多少个接口,在项目中虽然有用到swagger,但是并不是所有的接口都加了swagger需要的注解,这个时候就想象到了通过反射来实现,但是前提是需要获取Spring容器里面所有的Bean,那么如何获取呢,且看分析如下:
 

我们知道Spring容器在启动的时候会初始化一个默认的BeanFactory,这个BeanFactory就是org.springframework.beans.factory.support.DefaultListableBeanFactory,也就是在著名的AbstractApplicationContext的refresh方法里面,获取BeanFactory的时候:

 根据类的继承关系图,我们会发现DefaultListableBeanFactory实现了ListableBeanFactory这么一个接口,它里面有个方法可以获取到Srping容器里面所有的Bean名称:

而我们知道我们通常在获取Bean的时候要么通过bean名称,要么通过bean类型,也就是我们通常用的applicationContext.getBean(beanName)和applicationContext.getBean(Class type)这两个方法,那么要获取Spring容器里面所有的bean以及统计有多少个接口就是下面的的代码了:
 

    public void getBean() {
        //获取所有的beanName
        String[] beans = applicationContext
                .getBeanDefinitionNames();
        int i = 0;
        for (String beanName : beans) {
            //根据名称找到所有的bean
            System.err.println(applicationContext.getBean(beanName));
            //根据Bean名称找到对应的Class,然后通过反射来统计RestController、Controller、RequestMapping的数量
            Class<?> beanType = applicationContext
                    .getType(beanName);
            RestController restController = beanType.getAnnotation(RestController.class);
            Controller controller = beanType.getAnnotation(Controller.class);
            if (restController != null || controller != null) {
                Method[] declaredMethods = beanType.getDeclaredMethods();
                for (Method declaredMethod : declaredMethods) {
                    if (declaredMethod.getAnnotation(RequestMapping.class) != null) {
                        i++;
                    }
                }
            }
        }
        System.err.println("接口数量:" + i);
    }

第二种方法:spring已经提供了方便获取指定注解的所有的bean和方法:,比如下面的代码就可以获取所有带有@RequestMapping的注解的方法

public void getRequestMappingMethods() {
        String[] beanDefinitionNames = applicationContext.getBeanNamesForType(Object.class, false, true);
        for (String beanDefinitionName : beanDefinitionNames) {
            Object bean = null;
            Lazy onBean = applicationContext.findAnnotationOnBean(beanDefinitionName, Lazy.class);
            if (onBean != null) {
                continue;
            } else {
                bean = applicationContext.getBean(beanDefinitionName);
            }
            Map<Method, RequestMapping> annotatedMethods = null;   // referred to :org.springframework.context.event.EventListenerMethodProcessor.processBean
            try {
                annotatedMethods = MethodIntrospector.selectMethods(bean.getClass(),
                        new MethodIntrospector.MetadataLookup<RequestMapping>() {
                            @Override
                            public RequestMapping inspect(Method method) {
                                return AnnotatedElementUtils.findMergedAnnotation(method, RequestMapping.class);
                            }
                        });
            } catch (Throwable ex) {
                ex.printStackTrace();
            }
            if (annotatedMethods == null || annotatedMethods.isEmpty()) {
                continue;
            }
            for (Map.Entry<Method, RequestMapping> methodXxlJobEntry : annotatedMethods.entrySet()) {
                Method executeMethod = methodXxlJobEntry.getKey();
                RequestMapping xxlJob = methodXxlJobEntry.getValue();
                // regist
                System.err.println("executeMethod:"+executeMethod);
            }
        }
    }

猜你喜欢

转载自blog.csdn.net/qq_17805707/article/details/132102352