赞
踩
写了个自定义注解,想获取自定义注解的属性,或者标在方法上的注解上的属性
//获取自定义注解的配置的所有bean final Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(EnableRetryRabbitMq.class); for (String key : beansWithAnnotation.keySet()) { String scanPackage = "com.pkk"; //获取指定bean的注解为EnableRetryRabbitMq.class的注解属性 final EnableRetryRabbitMq annotation = AnnotationUtils.findAnnotation(beansWithAnnotation.get(key).getClass(), EnableRetryRabbitMq.class); if (null != annotation && StringUtils.isNotBlank(annotation.scanBasePackages())) { scanPackage = annotation.scanBasePackages(); } //注入bean(自己封装的方法,详情看下面) RetrySpringUtil.handleRegisterBeanWithSpringToInitConfigurerationBean(applicationContext); } -- 说明 ①:applicationContext是ApplicationContent,可以通过实现ApplicationContextAware来获取
** * @Description: 处理并注册bean * @Param: [applicationContext, scanPackage] * @return: void * @Author: pkk * @Date: 2019/9/6 0006 下午 1:35 */ public static void handleRegisterBeanWithSpringToInitConfigurerationBean(ApplicationContext applicationContext) { //获取自定义注解的配置 final Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(InitRetryRabbitMq.class); for (String key : beansWithAnnotation.keySet()) { //Spring 代理类导致Method无法获取,这里使用AopUtils.getTargetClass()方法 Method[] methods = ReflectionUtils.getAllDeclaredMethods(AopUtils.getTargetClass(beansWithAnnotation.get(key).getClass())); for (Method method : methods) { //获取指定方法上的注解的属性 final InitRetryRabbitMq initRetryRabbitMq = AnnotationUtils.findAnnotation(method, InitRetryRabbitMq.class); if (null != initRetryRabbitMq) { //验证必要的注解的属性 String queueName = Optional.ofNullable(initRetryRabbitMq.queueName()).orElseThrow(() -> new IllegalArgumentException("Please specify the queue name of the queue!")); //多个bean的时候相当于起个别名 String registerBean = queueName + "InitConfigurerationBean"; //将bean注册到Spring容器中,通过构造函数的方式进行注入 SpringRegisterBean.registerBean((ConfigurableApplicationContext) applicationContext, registerBean, InitConfigurerationBean.class, initRetryRabbitMq, applicationContext); log.info("The registration bean is " + registerBean + ",Configuration information is " + JSONObject.toJSONString(initRetryRabbitMq)); } } } }
采用BeanDefinitionBuilder(bean定义构造器)使用构造函数的方式注入bean
/** * 主动向Spring容器中注册bean * * @param applicationContext Spring容器 * @param beanName BeanName * @param registerBeanClazz 将要注册的bean的类 * @param args 构造方法的必要参数,顺序和类型要求和clazz中定义的一致 * @return 返回注册到容器中的bean对象 */ public static <T> T registerBean(ConfigurableApplicationContext applicationContext, String beanName, Class<T> registerBeanClazz, Object... args) { //容器中是否已经包含此bean if (applicationContext.containsBean(beanName)) { Object bean = applicationContext.getBean(beanName); //的类或接口是否相同,或是否是其超类或超接口。如果是则返回 true;否则返回 false。如果该 Class 表示一个基本类型,且指定的 Class 参数正是该 Class 对象,则该方法返回 true;否则返回 false if (bean.getClass().isAssignableFrom(registerBeanClazz)) { return (T) bean; } else { throw new RuntimeException("BeanName 重复 " + beanName); } } //Spring的bean的定义构造器 BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(registerBeanClazz); //给要注册的bean设置构造函数相应的参数,注意,顺序要相同 for (Object arg : args) { beanDefinitionBuilder.addConstructorArgValue(arg); } //获取原始的bean BeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition(); //获取bean定义注册的工厂 BeanDefinitionRegistry beanFactory = (BeanDefinitionRegistry) applicationContext.getBeanFactory(); //开启注册bean到Sring容器中 beanFactory.registerBeanDefinition(beanName, beanDefinition); return applicationContext.getBean(beanName, registerBeanClazz); }
package com.pkk.log.web.configure; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.stereotype.Component; /** * @description: bean创建之后的操作, 会调用postProcessAfterInitialization * @author: peikunkun * @create: 2019-09-04 17:19 **/ @Slf4j @Component public class BeanCreateProcessor implements BeanPostProcessor { /** * @Description: bean初始化之前的曹组 * @Param: [bean, beanName] * @return: java.lang.Object * @Author: peikunkun * @Date: 2019/9/6 0006 下午 3:10 */ @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { log.info("bean ->" + beanName + "初始化之前的操作"); return bean; } /** * @Description: bean创建之后的操作 * @Param: [bean, beanName] * @return: java.lang.Object * @Author: peikunkun * @Date: 2019/9/4 0004 下午 5:42 */ @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { log.info("bean ->" + beanName + "初始化之后的操作"); return bean; } } @Slf4j @Component class InitializingBeanTest implements InitializingBean { public void init() { System.out.println("init-method is called"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("afterPropertiesSet-method is called"); } } class mainTest { public static void main(String[] args) { System.out.println("执行顺序:\n" + "afterPropertiesSet 和init-method之间的执行顺序是afterPropertiesSet 先执行,init-method 后执行。\n" + "从BeanPostProcessor的作用,可以看出最先执行的是postProcessBeforeInitialization,然后是afterPropertiesSet," + "然后是init-method,然后是postProcessAfterInitialization。"); } }
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。