技术spring容器注入,springboot启动,javassist动态给类产生注解
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(ImportEventServiceDefineIdRegistrar.class) /** * EventService使用的启用类 */ public @interface EnableEventService { /** * 扫描路径 * @return */ String[] basePackages() default { "com.thoughtworks" }; /** * 支持的方式,现支持3种:id,code,all * @return */ BillEventSupportType supportType() default BillEventSupportType.ALL; }
/** * EventServiceDefineId的注入,同时把DefineCode放入DefineCodeBeanDefinitionRegistrarContext中,在spring启动前,再处理DefineCodeBeanDefinitionRegistrarContext */ public class ImportEventServiceDefineIdRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) { //注入billEventListener,billEventListener为什么不是用@Compoent注解?为了在不启用的情况下,不影响原来逻辑 CoreBeanDefinitionRegistrarContext.register(beanDefinitionRegistry); //设置DefineCodeBeanDefinitionRegistrarContext的beandefinition的注册器 DefineCodeBeanDefinitionRegistrarContext.setBeanDefinitionRegistry(beanDefinitionRegistry); //获取注解的扫描器 EventServiceClassPathScanningCandidateComponentProvider classPathScanningCandidateComponentProvider = new EventServiceClassPathScanningCandidateComponentProvider(); //获取EnableEventService注解上配置的属性 Map<String, Object> attrs = annotationMetadata.getAnnotationAttributes(EnableEventService.class.getName()); //获取需要扫描的路径 ScanParam scanParam = new ScanParam((String[])attrs.get("basePackages"), (BillEventSupportType)attrs.get("supportType")); //遍历扫描路径 for (String basePackage : scanParam.getBasePackages()) { //扫描得到的BeanDefinition的集合 Set<BeanDefinition> eventServiceSet = classPathScanningCandidateComponentProvider.findCandidateComponents(basePackage); //遍历集合注入到spring容器中 for (BeanDefinition eventServiceBeanDefinition : eventServiceSet) { //生成beanid Set<String> beanIds = EventServiceBeanIdGenerator.getBeanIds(eventServiceBeanDefinition, scanParam); for (String beanId : beanIds) { if (beanId != null) { if (beanDefinitionRegistry.containsBeanDefinition(beanId)) { throw new EventServiceException(beanId + "在spring容器中已经存在"); } //放入spring容器 beanDefinitionRegistry.registerBeanDefinition(beanId, eventServiceBeanDefinition); } } } } } /** * EventService注解扫描器 */ class EventServiceClassPathScanningCandidateComponentProvider extends ClassPathScanningCandidateComponentProvider { @Override protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException { //只扫描3类注解 return metadataReader.getAnnotationMetadata().hasAnnotation(BillEventService.class.getName()) || metadataReader.getAnnotationMetadata().hasAnnotation(BoEventService.class.getName()) || metadataReader.getAnnotationMetadata().hasAnnotation(WfEventService.class.getName()); } } /** * 扫描参数 */ class ScanParam { private String[] basePackages; private BillEventSupportType billEventSupportType; public ScanParam(String[] basePackages, BillEventSupportType billEventSupportType) { this.basePackages = basePackages; this.billEventSupportType = billEventSupportType; } public String[] getBasePackages() { return basePackages; } public BillEventSupportType getBillEventSupportType() { return billEventSupportType; } } /** * eventService beanId生成器,策略模式分发到3类生成器去处理 */ static class EventServiceBeanIdGenerator { public static Set<String> getBeanIds(BeanDefinition eventServiceBeanDefinition, ScanParam scanParam) { try { Class clz = Class.forName(eventServiceBeanDefinition.getBeanClassName()); Annotation[] annotations = clz.getAnnotations(); if (annotations.length == 1) { Annotation serviceAnnotation = annotations[0]; return EventServiceBeanIdGeneratorEnum.getEventServiceBeanIdGeneraterEnum(serviceAnnotation.annotationType()).getBeanIds(eventServiceBeanDefinition, scanParam); } else { throw new EventServiceException("先申明正确的注解"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } return new HashSet<>(); } } /** * eventService beanId内部生成器,现有3类生成器 */ enum EventServiceBeanIdGeneratorEnum { /** * BillEventService注解beanid的生成器 */ BillEventServiceBeanIdGenerator(BillEventService.class) { @Override public Set<String> getBeanIds(BeanDefinition eventServiceBeanDefinition, ScanParam scanParam) { //获取service Class handlerClass = getHandlerClass(eventServiceBeanDefinition); Set<String> beanIds = new HashSet<>(); //获取services上的注解 BillEventService eventService = (BillEventService)handlerClass.getAnnotation(BillEventService.class); Set<String> billDefineIds = new HashSet<>(); //如果支持befineid模式,分解billdefineid if (scanParam.getBillEventSupportType() == BillEventSupportType.ALL || scanParam.getBillEventSupportType() == BillEventSupportType.DEFINEID) { String[] arr = eventService.billDefineId().split(","); billDefineIds.addAll(Arrays.asList(arr)); } //拿到类上的泛型注解 Type[] types = handlerClass.getGenericInterfaces(); if (types.length > 0) {//如果实现的是EventHandler接口 //得到泛型的具体类 Type type = types[0]; if (type != null) { for (String billDefineId : billDefineIds) { beanIds.add(getGenericEventClassName(type) + billDefineId); } //支持befinecode if (scanParam.getBillEventSupportType() == BillEventSupportType.ALL || scanParam.getBillEventSupportType() == BillEventSupportType.DEFINECODE) { String[] arr = eventService.billDefineCode().split(","); for (String billDefineCode : arr) { DefineCodeBeanDefinitionRegistrarContext.addDefineCodeBeanDefinition(getGenericEventClassName(type), billDefineCode, eventServiceBeanDefinition); } } } } else {//如果实现的是AbstractEventHandler抽象类 Type type = handlerClass.getGenericSuperclass(); if (type != null) { //得到泛型的具体类 for (String billDefineId : billDefineIds) { beanIds.add(getGenericEventClassName(type) + billDefineId); } //支持befinecode if (scanParam.getBillEventSupportType() == BillEventSupportType.ALL || scanParam.getBillEventSupportType() == BillEventSupportType.DEFINECODE) { String[] arr = eventService.billDefineCode().split(","); for (String billDefineCode : arr) { DefineCodeBeanDefinitionRegistrarContext.addDefineCodeBeanDefinition(getGenericEventClassName(type), billDefineCode, eventServiceBeanDefinition); } } } } return beanIds; } }, /** * WfEventService注解beanid的生成器 */ WfEventServiceBeanIdGenerator(WfEventService.class) { @Override public Set<String> getBeanIds(BeanDefinition eventServiceBeanDefinition, ScanParam scanParam) { //获取service Class handlerClass = getHandlerClass(eventServiceBeanDefinition); WfEventService eventService = (WfEventService)handlerClass.getAnnotation(WfEventService.class); Set<String> beanIds = new HashSet<>(); //支持befineid if (scanParam.getBillEventSupportType() == BillEventSupportType.ALL || scanParam.getBillEventSupportType() == BillEventSupportType.DEFINEID) { String[] billDefineIds = eventService.billDefineId().split(","); for (String billDefineId : billDefineIds) { beanIds.add(eventService.eventType().name() + billDefineId); } } //支持befinecode if (scanParam.getBillEventSupportType() == BillEventSupportType.ALL || scanParam.getBillEventSupportType() == BillEventSupportType.DEFINECODE) { String[] arr = eventService.billDefineCode().split(","); for (String billDefineCode : arr) { DefineCodeBeanDefinitionRegistrarContext.addDefineCodeBeanDefinition(eventService.eventType().name(), billDefineCode, eventServiceBeanDefinition); } } return beanIds; } }, /** * BoEventService注解beanid的生成器 */ BoEventServiceBeanIdGenerator(BoEventService.class) { @Override public Set<String> getBeanIds(BeanDefinition eventServiceBeanDefinition, ScanParam scanParam) { //获取service Class handlerClass = getHandlerClass(eventServiceBeanDefinition); BoEventService eventService = (BoEventService)handlerClass.getAnnotation(BoEventService.class); Set<String> beanIds = new HashSet<>(); String[] boDefineIds = eventService.boDefineId().split(","); for (String boDefineId : boDefineIds) { beanIds.add(boDefineId); } return beanIds; } }; //处理类上的注解class private Class eventServiceClass; EventServiceBeanIdGeneratorEnum(Class eventServiceClass) { this.eventServiceClass = eventServiceClass; } /** * 生成BeanDefinition的beanId * @param eventServiceBeanDefinition * @return */ protected abstract Set<String> getBeanIds(BeanDefinition eventServiceBeanDefinition, ScanParam scanParam); private Class getEventServiceClass() { return eventServiceClass; } /** * 根据serviceclass获取beanid的生成器 * @param eventServiceClass * @return */ private static EventServiceBeanIdGeneratorEnum getEventServiceBeanIdGeneraterEnum(Class eventServiceClass) { for (EventServiceBeanIdGeneratorEnum item : EventServiceBeanIdGeneratorEnum.values()) { if (item.getEventServiceClass() == eventServiceClass) { return item; } } return null; } private static Class getHandlerClass(BeanDefinition eventServiceBeanDefinition) { Class handlerClass = null; try { handlerClass = Class.forName(eventServiceBeanDefinition.getBeanClassName()); } catch (ClassNotFoundException e) { throw new EventServiceException(e.getMessage()); } return handlerClass; } /** * 获取泛型上类名 * @param type * @return */ private static String getGenericEventClassName(Type type) { if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType)type; Type[] actualTypeArgumentTypes = parameterizedType.getActualTypeArguments(); if (actualTypeArgumentTypes.length == 1) { Type actualTypeArgumentType = actualTypeArgumentTypes[0]; Class clz = null; try { clz = Class.forName(actualTypeArgumentType.getTypeName()); } catch (ClassNotFoundException e) { throw new EventServiceException(e.getMessage()); } //泛型参数是为ApplicationEvent if (ApplicationEvent.class.isAssignableFrom(clz)) { return firstChar2LowerCase(actualTypeArgumentType.getTypeName()); } else { throw new EventServiceException("不支持的泛型事件"); } } else { throw new EventServiceException("不支持的泛型事件"); } } throw new EventServiceException("不支持的泛型事件"); } /** * 包名取最后.的字母,并且首字母小写 * @param str * @return */ private static String firstChar2LowerCase(String str) { String lastStr = str.substring(str.lastIndexOf(".") + 1); return lastStr.substring(0, 1).toLowerCase() + lastStr.substring(1); } } }
/** * 核心BeanDefinition的注入 */ class CoreBeanDefinitionRegistrarContext { /** * 注入3类核心BeanDefinition * @param beanDefinitionRegistry */ public static void register(BeanDefinitionRegistry beanDefinitionRegistry) { //注入流程的监听 registerWfEventListener(beanDefinitionRegistry); //注入单据的监听 registerBillEventListeners(beanDefinitionRegistry); //注入ImportEventServiceDefineCodeRegistrar registerEventServiceDefineCodeRegistrar(beanDefinitionRegistry); } private static void registerWfEventListener(BeanDefinitionRegistry beanDefinitionRegistry) { registerWfEventListener(EndInstanceWFEventListener.class, WFEventType.END_INSTANCE, beanDefinitionRegistry); registerWfEventListener(EnterNodeWfEventListener.class, WFEventType.ENTER_NODE, beanDefinitionRegistry); registerWfEventListener(LeaveNodeWFEventListener.class, WFEventType.LEAVE_NODE, beanDefinitionRegistry); registerWfEventListener(TaskAssignWfEventListener.class, WFEventType.TASK_ASSIGN, beanDefinitionRegistry); } /** * 利用javassist动态的给类加上WFGlobalListener注解 * @param listenerClass * @param wfEventType * @param beanDefinitionRegistry */ private static void registerWfEventListener(Class listenerClass, WFEventType wfEventType, BeanDefinitionRegistry beanDefinitionRegistry) { try { CtClass ctClass = ClassPool.getDefault().makeClass(listenerClass.getName()); //设置别名,一个jvm只是存在一个名字的一个对象 ctClass.setName(listenerClass.getName() + "$" + wfEventType.name()); ConstPool constPool = ctClass.getClassFile().getConstPool(); AnnotationsAttribute annotationsAttribute = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag); javassist.bytecode.annotation.Annotation listenerAnnotation = new javassist.bytecode.annotation.Annotation(WFGlobalListener.class.getCanonicalName(), constPool); EnumMemberValue enumMemberValue = new EnumMemberValue(constPool); enumMemberValue.setType(WFEventType.class.getName()); enumMemberValue.setValue(wfEventType.name()); listenerAnnotation.addMemberValue("eventType", enumMemberValue); annotationsAttribute.addAnnotation(listenerAnnotation); ctClass.getClassFile().addAttribute(annotationsAttribute); Class clz = ctClass.toClass(); BeanDefinition beanDefinition = new GenericBeanDefinition(); beanDefinition.setBeanClassName(clz.getName()); beanDefinitionRegistry.registerBeanDefinition("wfEventListener$" + clz.getSimpleName(), beanDefinition); } catch (CannotCompileException e) { throw new EventServiceException(e.getMessage()); } } private static void registerBillEventListeners(BeanDefinitionRegistry beanDefinitionRegistry) { registerClass(BillAfterCommitEventListener.class, beanDefinitionRegistry); registerClass(BillAfterDeleteEventListener.class, beanDefinitionRegistry); registerClass(BillAfterSaveEventListener.class, beanDefinitionRegistry); registerClass(BillAfterValueChangeEventListener.class, beanDefinitionRegistry); registerClass(BillBeforeSaveEventListener.class, beanDefinitionRegistry); } private static void registerClass(Class clz, BeanDefinitionRegistry beanDefinitionRegistry) { BeanDefinition beanDefinition = new GenericBeanDefinition(); beanDefinition.setBeanClassName(clz.getName()); beanDefinitionRegistry.registerBeanDefinition("billEventListener$" + clz.getSimpleName(), beanDefinition); } /** * 注入definecode的处理 * @param beanDefinitionRegistry */ private static void registerEventServiceDefineCodeRegistrar(BeanDefinitionRegistry beanDefinitionRegistry) { BeanDefinition beanDefinition = new GenericBeanDefinition(); beanDefinition.setBeanClassName(ImportEventServiceDefineCodeRegistrar.class.getName()); beanDefinitionRegistry.registerBeanDefinition("importEventServiceDefineCodeRegistrar", beanDefinition); } }
class DefineCodeBeanDefinitionRegistrarContext { private static BeanDefinitionRegistry beanDefinitionRegistry; private static List<DefineCodeBeanDefinition> defineCodeBeanDefinitions = new ArrayList<>(); public static void setBeanDefinitionRegistry(BeanDefinitionRegistry registry) { beanDefinitionRegistry = registry; } public static void addDefineCodeBeanDefinition(String prefix, String defineCode, BeanDefinition beanDefinition) { defineCodeBeanDefinitions.add(new DefineCodeBeanDefinition(prefix, defineCode, beanDefinition)); } public static void registerBeanDefinition() { for (DefineCodeBeanDefinition defineCodeBeanDefinition : defineCodeBeanDefinitions) { //获取beanId String beanId = defineCodeBeanDefinition.getPrefix() + defineCode2Id(defineCodeBeanDefinition.getDefineCode()); if (beanDefinitionRegistry.containsBeanDefinition(beanId)) { throw new EventServiceException(beanId + "在spring容器中已经存在"); } //放入spring容器 beanDefinitionRegistry.registerBeanDefinition(beanId, defineCodeBeanDefinition.getBeanDefinition()); } } /** * 查询t_bill_type,把definecode转为defineid * @param defineCode * @return */ private static String defineCode2Id(String defineCode) { return BaseObjectIdUtil.getBillDefineIdByCode(defineCode); } static class DefineCodeBeanDefinition { //前缀=提交事件名或流程事件名 private String prefix; private String defineCode; private BeanDefinition beanDefinition; public DefineCodeBeanDefinition(String prefix, String defineCode, BeanDefinition beanDefinition) { this.prefix = prefix; this.defineCode = defineCode; this.beanDefinition = beanDefinition; } public String getPrefix() { return prefix; } public String getDefineCode() { return defineCode; } public BeanDefinition getBeanDefinition() { return beanDefinition; } } }
/** * definecode注入,实现原理:在spring实例化所有bean后,启动前,调用dao层把definecode转化为defineid * 为什么这么做:dao层在加载bean时,还没有加载到spring容器,无法被调用 */ public class ImportEventServiceDefineCodeRegistrar implements CommandLineRunner { @Override public void run(String... args) throws Exception { DefineCodeBeanDefinitionRegistrarContext.registerBeanDefinition(); } }