spring的事件监听与spring的bean动态注入

一、事件监听

  (1)、创建事件传输的对象

public class EventDTO {

    private String name;
    private String type;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    @Override
    public String toString() {
        return name +":"+type;
    }
}

  (2)、创建事件对象

public class TestEvent extends ApplicationEvent {

    public TestEvent(Object source) {
        super(source);
    }

    public EventDTO getDTO(){
        return (EventDTO) this.source;
    }
}

  (3)、发布事件并监听事件

    @Autowired
    private ApplicationEventPublisher publisher;

    @RequestMapping("/test/{tableId}")
    public String getIcon(@PathVariable String tableId) {
        EventDTO dto = new EventDTO();
        dto.setName("lik");
        dto.setType("11");
        publisher.publishEvent(new TestEvent(dto));
        var a = "test";
        return a;
    }

    @EventListener
    public void onTestEvent(TestEvent event){
        System.out.println("接收到消息了:event = [" + event.getDTO() + "]");
    }

二、bean的动态注入

  spring中的@service@controller@component等注解的类怎样注入spring容器的呢?发现是通过ImportBeanDefinitionRegistrar的,所有只需要新建一个类实现ImportBeanDefinitionRegistrar接口,然后

在有@configuration的类上@Import(MyImportBeanDefinitionRegistrar.class),然后就可以扫描注入了。自定义@Comp注解让它实现类似于@component的功能。

  (一)创建扫描的注解

@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
public @interface Comp {
    String value() default "";
}

  (二)创建注册类

public class MyImportBeanDefinitionRegistrar
        implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, BeanFactoryAware
{

    private ResourceLoader resourceLoader;

    private BeanFactory beanFactory;

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        MyClassPathBeanDefinitionScanner scanner = new MyClassPathBeanDefinitionScanner(registry, false);
        scanner.setResourceLoader(resourceLoader);
        scanner.registerFilters();
        scanner.doScan("com.lik.springsecurity.securitydemo");
    }

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

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }
}

  (三)registerBeanDefinitions方法需要一个scanner新建一个scanner

public class MyClassPathBeanDefinitionScanner extends ClassPathBeanDefinitionScanner {

    public MyClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
        super(registry, useDefaultFilters);
    }

    protected void registerFilters() {
        addIncludeFilter(new AnnotationTypeFilter(Comp.class));
    }

    @Override
    protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
        return super.doScan(basePackages);
    }
}

  然后在有@Configuration的类上加入注解@Import(MyImportBeanDefinitionRegistrar.class),然后自定义的@Comp注解就可以像@component一样使用了。

Component
posted @ 2019-05-27 17:39  fantastiLi  阅读(499)  评论(0)    收藏  举报