Spring中自定义注解

前言

在我的理解中,从功能上区分,注解分为两类,一类是类似于@Service,定义某种性质,通常在项目启动时就会被注册使用;一类是类似于@Log,实现特定的具体功能,通常在项目运行过程中使用。
在日常开发中,总结了在spring中这两种注解的常用开发方式,备忘。

项目启动时使用的注解

此处参考xxl-job中的@XxlJob注解

@XxlJob注解使用在方法上,标注该方法为调度器远程调用的执行器方法。类似于spring中的定时任务,只不过控制方为远程调度器,具体可以参考 xxl-job详细文档

// 获取所有的单例beanDefinition,第一个参数表示type,第二个参数表示是否接受非单例,第三个参数表示接受懒加载和FactoryBeans
String[] beanDefinitionNames = applicationContext.getBeanNamesForType(Object.class, false, true);
for (String beanDefinitionName : beanDefinitionNames) {
	// 获取bean
    Object bean = applicationContext.getBean(beanDefinitionName);
   // 获取XxlJob注解的方法集合
    Map<Method, XxlJob> annotatedMethods = null;   // referred to :org.springframework.context.event.EventListenerMethodProcessor.processBean
    try {
        annotatedMethods = MethodIntrospector.selectMethods(bean.getClass(),
                new MethodIntrospector.MetadataLookup<XxlJob>() {
                    @Override
                    public XxlJob inspect(Method method) {
                        return AnnotatedElementUtils.findMergedAnnotation(method, XxlJob.class);
                    }
                });
    } catch (Throwable ex) {
        logger.error("xxl-job method-jobhandler resolve error for bean[" + beanDefinitionName + "].", ex);
    }
    if (annotatedMethods==null || annotatedMethods.isEmpty()) {
        continue;
    }
   //遍历方法集合,实现特定功能
    for (Map.Entry<Method, XxlJob> methodXxlJobEntry : annotatedMethods.entrySet()) {
        Method method = methodXxlJobEntry.getKey();
        XxlJob xxlJob = methodXxlJobEntry.getValue();
        if (xxlJob == null) {
            continue;
        }

        String name = xxlJob.value();
        if (name.trim().length() == 0) {
            throw new RuntimeException("xxl-job method-jobhandler name invalid, for[" + bean.getClass() + "#" + method.getName() + "] .");
        }
        if (loadJobHandler(name) != null) {
            throw new RuntimeException("xxl-job jobhandler[" + name + "] naming conflicts.");
        }

        // execute method
        if (!(method.getParameterTypes().length == 1 && method.getParameterTypes()[0].isAssignableFrom(String.class))) {
            throw new RuntimeException("xxl-job method-jobhandler param-classtype invalid, for[" + bean.getClass() + "#" + method.getName() + "] , " +
                    "The correct method format like \" public ReturnT<String> execute(String param) \" .");
        }
        if (!method.getReturnType().isAssignableFrom(ReturnT.class)) {
            throw new RuntimeException("xxl-job method-jobhandler return-classtype invalid, for[" + bean.getClass() + "#" + method.getName() + "] , " +
                    "The correct method format like \" public ReturnT<String> execute(String param) \" .");
        }
        method.setAccessible(true);

        // init and destory
        Method initMethod = null;
        Method destroyMethod = null;
   	// 初始化方法
        if (xxlJob.init().trim().length() > 0) {
            try {
                initMethod = bean.getClass().getDeclaredMethod(xxlJob.init());
                initMethod.setAccessible(true);
            } catch (NoSuchMethodException e) {
                throw new RuntimeException("xxl-job method-jobhandler initMethod invalid, for[" + bean.getClass() + "#" + method.getName() + "] .");
            }
        }
        // 销毁方法
        if (xxlJob.destroy().trim().length() > 0) {
            try {
                destroyMethod = bean.getClass().getDeclaredMethod(xxlJob.destroy());
                destroyMethod.setAccessible(true);
            } catch (NoSuchMethodException e) {
                throw new RuntimeException("xxl-job method-jobhandler destroyMethod invalid, for[" + bean.getClass() + "#" + method.getName() + "] .");
            }
        }

        // registry jobhandler 对该方法进行注册,用于远程调度器进行远程调度
        registJobHandler(name, new MethodJobHandler(bean, method, initMethod, destroyMethod));
    }
}

1、XxlJobSpringExecutor中implements ApplicationContextAware, SmartInitializingSingleton,获得applicationContext,并且在spring项目加载完成后,调用afterSingletonsInstantiated()方法,实现特定功能。
2、通过applicationContext对象获取所有的beanDefinitionNames。
3、获取XxlJob注解的方法集合。
4、对方法集合进行遍历,获取注解的属性,用于实现特定功能;
5、获取初始化方法和销毁方法。
6、对该方法进行注册,用于调度器远程调用。

项目过程中使用的注解

Spring中的AOP切面,可以很方便的实现项目过程中的注解开发,可以参考Spring项目中自定义注解的使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

siihmc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值