美文网首页技术
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