实战@Import注解 加事件监听模式[杂乱]

在这里插入图片描述

@Java110ListenerDiscovery(
        listenerPublishClass = ServiceDataFlowEventPublishing.class,
        basePackages = {"com.lvhao.api.listener"})
public class ApiApplicationStart {
    public static void main(String[] args) {
        SpringApplication.run(ApiApplicationStart.class);
    }

处理 Java110ListenerDiscovery注解	
package com.java110.core.annocation;


import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

import java.beans.Introspector;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * 自定义侦听扫描
 * Created by wuxw on 2018/7/2.
 */
public class Java110ListenerDiscoveryRegistrar
        implements ImportBeanDefinitionRegistrar,
        ResourceLoaderAware, BeanClassLoaderAware {

    private ResourceLoader resourceLoader;

    private ClassLoader classLoader;

    public Java110ListenerDiscoveryRegistrar(){

    }

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        try {
            registerListener(importingClassMetadata,registry);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        this.classLoader = classLoader;
    }

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    /**
     * 注册侦听
     * @param metadata
     * @param registry
     */
    public void registerListener(AnnotationMetadata metadata,
                                 BeanDefinitionRegistry registry) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        ClassPathScanningCandidateComponentProvider scanner = getScanner();

        scanner.setResourceLoader(this.resourceLoader);
        Set<String> basePackages;
        Map<String, Object> attrs = metadata
                .getAnnotationAttributes(Java110ListenerDiscovery.class.getName());

        Object listenerPublishClassObj =  attrs.get("listenerPublishClass");

        Assert.notNull(listenerPublishClassObj,"Java110ListenerDiscovery 没有配置 listenerPublishClass 属性");

        Class<?> listenerPublishClass = (Class<?>) listenerPublishClassObj;

        AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter(
                Java110Listener.class);

        scanner.addIncludeFilter(annotationTypeFilter);
        basePackages = getBasePackages(metadata);

        for (String basePackage : basePackages) {
            Set<BeanDefinition> candidateComponents = scanner
                    .findCandidateComponents(basePackage);
            for (BeanDefinition candidateComponent : candidateComponents) {
                if (candidateComponent instanceof AnnotatedBeanDefinition) {
                    // verify annotated class is an interface
                    AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition) candidateComponent;
                    AnnotationMetadata annotationMetadata = beanDefinition.getMetadata();

                    Map<String, Object> attributes = annotationMetadata
                            .getAnnotationAttributes(
                                    Java110Listener.class.getCanonicalName());

                    String beanName = getListenerName(attributes,beanDefinition);

                    /*BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(beanDefinition, beanName);
                    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);*/
                    Method method = listenerPublishClass.getMethod("addListener",String.class);
                    method.invoke(beanName,null);

                }
            }
        }
    }

    protected ClassPathScanningCandidateComponentProvider getScanner() {
        return new ClassPathScanningCandidateComponentProvider(false) {

            @Override
            protected boolean isCandidateComponent(
                    AnnotatedBeanDefinition beanDefinition) {
                if (beanDefinition.getMetadata().isIndependent()) {
                    // TODO until SPR-11711 will be resolved
                    if (beanDefinition.getMetadata().isInterface()
                            && beanDefinition.getMetadata()
                            .getInterfaceNames().length == 1
                            && Annotation.class.getName().equals(beanDefinition
                            .getMetadata().getInterfaceNames()[0])) {
                        try {
                            Class<?> target = ClassUtils.forName(
                                    beanDefinition.getMetadata().getClassName(),
                                   Java110ListenerDiscoveryRegistrar.this.classLoader);
                            return !target.isAnnotation();
                        }
                        catch (Exception ex) {
                            this.logger.error(
                                    "Could not load target class: "
                                            + beanDefinition.getMetadata().getClassName(),
                                    ex);

                        }
                    }
                    return true;
                }
                return false;

            }
        };
    }

    protected Set<String> getBasePackages(AnnotationMetadata importingClassMetadata) {
        Map<String, Object> attributes = importingClassMetadata
                .getAnnotationAttributes(Java110ListenerDiscovery.class.getCanonicalName());

        Set<String> basePackages = new HashSet<String>();
        for (String pkg : (String[]) attributes.get("value")) {
            if (StringUtils.hasText(pkg)) {
                basePackages.add(pkg);
            }
        }
        for (String pkg : (String[]) attributes.get("basePackages")) {
            if (StringUtils.hasText(pkg)) {
                basePackages.add(pkg);
            }
        }
        if (basePackages.isEmpty()) {
            basePackages.add(
                    ClassUtils.getPackageName(importingClassMetadata.getClassName()));
        }
        return basePackages;
    }


    /**
     * 获取名称
     * @param listeners
     * @param beanDefinition
     * @return
     */
    private String getListenerName(Map<String, Object> listeners, AnnotatedBeanDefinition beanDefinition) {
        if (listeners == null) {
            String shortClassName = ClassUtils.getShortName(beanDefinition.getBeanClassName());
            return Introspector.decapitalize(shortClassName);
        }
        String value = (String) listeners.get("value");
        if (!StringUtils.hasText(value)) {
            value = (String) listeners.get("name");
        }
        if (StringUtils.hasText(value)) {
            return value;
        }

        String shortClassName = ClassUtils.getShortName(beanDefinition.getBeanClassName());
        value = Introspector.decapitalize(shortClassName);
        return value;
    }


}

package com.java110.core.annocation;

import org.springframework.context.annotation.Import;

import java.lang.annotation.*;

/**
 * 侦听注入
 * Created by wuxw on 2018/7/2.
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(Java110ListenerDiscoveryRegistrar.class)
public @interface Java110ListenerDiscovery {

    String[] basePackages() default {};

    String[] value() default {};

    Class<?> listenerPublishClass();
}

package com.java110.core.annocation;

import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Component;

import java.lang.annotation.*;

/**
 * Created by wuxw on 2018/7/2.
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Java110Listener {
    @AliasFor("name")
    String value() default "";

    @AliasFor("value")
    String name() default "";
}


// 数据流事件发布
public class ServiceDataFlowEventPublish {
    private static final Map<String, List<ServiceListener>> cacheListenerMap = new HashMap<String, List<ServiceListener>>();
    /**
     * 保存侦听实例信息,一般启动时加载
     */
    private static final List<String> listeners = new ArrayList<String>();
    private static Executor taskExecutor;

    /**
     * 添加 侦听,这个只有启动时,单线程 处理,所以是线程安全的
     *
     * @param listener
     */
    public static void addListener(String listener) {
        listeners.add(listener);
    }

    public static List<String> getListeners() {
        return listeners;
    }
    public static void multicastEvent(String police, String asyn) throws Exception{
        List<ServiceListener>listeners = getListener(police);
        if ("A".equals(asyn)) {
            Executor executor = getTaskExecutor();
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    try {

                        // 一个线程池
                        invokeLisnerers(listeners, police);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        } else {
            invokeLisnerers(listeners, police);
        }


    }

    private static synchronized Executor getTaskExecutor() {
        if (  null==taskExecutor) {
            taskExecutor = Executors.newFixedThreadPool(4);
        }
        return taskExecutor;
    }

    private static void invokeLisnerers(List<ServiceListener> listeners, String police) throws InterruptedException {
        for (ServiceListener listener : listeners) {
            listener.invokeMethod(police);
        }
    }

    private static List<ServiceListener> getListener(String police) {
        if (cacheListenerMap.containsKey(police)) {
            return cacheListenerMap.get(police);
        }
      List<ServiceListener> serviceListener = new ArrayList<>();
        for (String listenerBeanName : getListeners()) {
            ServiceListener listener = ApplicationContextFactory.getBean(listenerBeanName, ServiceListener.class);
            serviceListener.add(listener);

        }
        if(!serviceListener.isEmpty())
            cacheListenerMap.put(police,serviceListener);
        return serviceListener;
    }
}
详情参考 大佬git地址
https://gitee.com/java110/MicroCommunityWeb.git

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值