美文网首页技术
SpringBoot 获取Bean和方法调用

SpringBoot 获取Bean和方法调用

作者: Tinyspot | 来源:发表于2022-10-14 21:39 被阅读0次

    1. ApplicationContext

    @Component
    public class SpringBeanUtils implements ApplicationContextAware {
    
        private static final List<Class> PRIMARY_CLASS = Arrays.asList(Integer.class, Boolean.class,
                Double.class, Byte.class, Short.class, Long.class, Float.class, BigDecimal.class, String.class);
    
        private static ApplicationContext applicationContext;
    
        public static ApplicationContext getApplicationContext() {
            return applicationContext;
        }
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            SpringBeanUtils.applicationContext = applicationContext;
        }
    
        public static <T> T getBean(Class<T> clazz) {
            return applicationContext.getBean(clazz);
        }
    
        public static <T> Object getBean(String beanName) {
            return applicationContext.getBean(beanName);
        }
    
        public static Method getMethod(Class<?> proxyObject, String methodName) {
            Method[] methods = proxyObject.getMethods();
            for (Method method : methods) {
                if (method.getName().equals(methodName)) {
                    return method;
                }
            }
            return null;
        }
    
        /**
         * 获取方法实际参数
         */
        public static List<Object> getMethodParamList(Method method, Map<String, String> paramMap) throws Exception {
            List<Object> objects = new ArrayList<>();
    
            DefaultParameterNameDiscoverer nameDiscoverer = new DefaultParameterNameDiscoverer();
            for (Class<?> parameterType : method.getParameterTypes()) {
                Object obj = null;
                if (PRIMARY_CLASS.contains(parameterType)) {
                    obj = paramMap.get(parameterType.getTypeName());
                    // obj = ConvertUtils.convert(obj, parameterType);
                } else if (!parameterType.isPrimitive()) {
                    obj = getInstance(parameterType);
                    // 将 map 拷贝到 bean 中
                    String value = paramMap.get(parameterType.getTypeName());
                    // org.apache.commons.beanutils.BeanUtils;
                    BeanUtils.populate(obj, JSON.parseObject(value));
                }
                objects.add(obj);
            }
            return objects;
        }
    
        /**
         * 获取类型实例
         * @param parameterType
         * @return
         */
        private static Object getInstance(Class<?> parameterType) throws Exception {
            if (parameterType.isAssignableFrom(List.class)) {
                return new ArrayList<>();
            } else if (parameterType.isAssignableFrom(Map.class)) {
                return new HashMap<>();
            } else if (parameterType.isAssignableFrom(Set.class)) {
                return new HashSet<>();
            }
            return parameterType.newInstance();
        }
    }
    

    1.1 获取 bean 和方法

    @RestController
    // @RequestMapping("/index")
    public class IndexController {
        
        /**
         * 获取所有的bean
         */
        @RequestMapping("/getBeans")
        public String getBeans() {
            String[] beanDefinitionNames = SpringBeanUtils.getApplicationContext().getBeanDefinitionNames();
            List<String> beanNames = Arrays.stream(beanDefinitionNames)
                    .filter(str -> !str.startsWith("org.") && !str.startsWith("spring."))
                    .collect(Collectors.toList());
            return JSON.toJSONString(beanNames);
        }
    
        /**
         * 测试 Bean 名称
         */
        @RequestMapping("/getBeanName")
        public String getBeanName(String name) {
            return Introspector.decapitalize(name);
        }
    
        @RequestMapping("/getMethods")
        public String getMethods(String beanName) {
            List<String> list = new ArrayList<>();
    
            Object beanObj = SpringBeanUtils.getBean(beanName);
            Method[] methods = ReflectionUtils.getUniqueDeclaredMethods(beanObj.getClass());
            for (Method method : methods) {
                StringBuffer buffer = new StringBuffer(method.getName());
                Type[] genericParameterTypes = method.getGenericParameterTypes();
                buffer.append("(");
                for (Type type : genericParameterTypes) {
                    buffer.append(type.getTypeName()).append(",");
                }
                if (genericParameterTypes.length > 0) {
                    // 删除最后一个 ,
                    buffer.deleteCharAt(buffer.length() - 1);
                }
                buffer.append(")");
                list.add(buffer.toString());
            }
            return JSON.toJSONString(list);
        }
    }
    

    请求示例 http://localhost:8020/getMethods?beanName=greetService

    1.2 方法调用

     <dependency>
        <groupId>commons-beanutils</groupId>
        <artifactId>commons-beanutils</artifactId>
        <version>1.9.4</version>
    </dependency>
    
        /**
         * 方法调用
         */
        @RequestMapping("/method/demo")
        public String methodDemo() throws Exception {
            Map<String, String> paramMap = new HashMap<>();
            paramMap.put("com.boot.train.kit.pojo.User", "{\"name\":\"Tinyspot\", \"age\":20}");
            paramMap.put("java.lang.String", "dev");
    
            String method = "greeting";
            Object proxyObj = SpringBeanUtils.getBean("greetService");
            Method proxyMethod = SpringBeanUtils.getMethod(proxyObj.getClass(), method);
            List<Object> parameters = SpringBeanUtils.getMethodParamList(proxyMethod, paramMap);
            Object result = proxyMethod.invoke(proxyObj, parameters.toArray());
            return result.toString();
        }
    
        @RequestMapping("/invoke/method")
        public String invokeMethod(String beanName, String methodName, Map<String, String> paramMap) {
            Object beanObj = SpringBeanUtils.getBean(beanName);
            // org.springframework.util.ReflectionUtils;
            Method method = ReflectionUtils.findMethod(beanObj.getClass(), methodName);
            Object result = ReflectionUtils.invokeMethod(method, beanObj);
            return result.toString();
        }
    
    @Service("greetService")
    public class GreetServiceImpl implements GreetService {
    
        @Override
        public String greet() {
            return "Hello";
        }
    
        @Override
        public String greeting(User user, String environment) {
            System.out.println("greeting run..." + JSON.toJSONString(user) + environment);
            return JSON.toJSONString(user) + "; " + environment;
        }
    }
    

    3. HttpServletRequest

    分析 HttpServletRequest 如何注入的
    org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

    @RestController
    @RequestMapping("/web")
    public class ConcreteController {
        @Resource
        private HttpServletRequest request;
    
        @RequestMapping("/request")
        public String request(HttpServletRequest request) {
            System.out.println(this.request.getClass());
            System.out.println(this.request.getParameterMap());
        }
    }
    

    3.1 方式二

    @RestController
    @RequestMapping("/web")
    public class ConcreteController {
        @RequestMapping("/request")
        public String request(HttpServletRequest request) {
            System.out.println(request.getClass());
            return "over";
        }
    
        @RequestMapping("/request2")
        public String servletRequest() {
            // 从请求上下文获取Request对象
            ServletRequestAttributes cast = ServletRequestAttributes.class.cast(RequestContextHolder.getRequestAttributes());
            HttpServletRequest request = cast.getRequest();
            return JSON.toJSONString(request.getClass());
        }
    }
    

    4. 其他

    4.1 获取 IP

        @RequestMapping("/ip/address")
        public String ipAddress() {
            String hostAddress = null;
            try {
                InetAddress localHost = InetAddress.getLocalHost();
                hostAddress = localHost.getHostAddress();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
            return hostAddress;
        }
    

    4.2 @PostConstruct 注解

    • JDK 提供的注解
        /**
         * ObjectFactoryDelegatingInvocationHandler
         * WebApplicationContextUtils
         */
        @PostConstruct
        public void after() {
            System.out.println(this.request.getClass());
        }
    

    相关文章

      网友评论

        本文标题:SpringBoot 获取Bean和方法调用

        本文链接:https://www.haomeiwen.com/subject/ntnqzrtx.html