java无法注册监听器_在spring中使用自定义注解注册监听器的方法

接口回调

监听器本质上就是利用回调机制,在某个动作发生前或后,执行我们自己的一些代码。在java语言中,可以使用接口来实现。

实现一个监听器案例

为了方便,直接在spring环境中定义:以工作(work)为例,定义工作开始时(或结束时)的监听器。

1. 定义回调的接口

package com.yawn.demo.listener;

/**

* @author Created by yawn on 2018-01-21 13:53

*/

public interface WorkListener {

void onStart(String name);

}

2. 定义动作

package com.yawn.demo.service;

import com.yawn.demo.listener.WorkListener;

/**

* @author Created by yawn on 2018-01-21 13:39

*/

@Service

public class MyService {

@Resource

private PersonService personService;

private WorkListener listener;

public void setWorkListener(WorkListener workListener) {

this.listener = workListener;

}

public void work(String name) {

listener.onStart(name);

personService.work();

}

}

动作work为一个具体的方法,在work()方法的适当时机,调用前面定义的接口。此外,在这个动作定义类中,需要提高设置监听器的方法。

3. 监听测试

@RunWith(SpringRunner.class)

@SpringBootTest

public class DemoSpringAnnotationApplicationTests {

@Resource

private MyService myService;

@Test

public void test1() {

//www.cppcns.com 接口设置监听器

myService.setWorkListener(new WorkListener() {

@Override

public void onStart(String name) {

System.out.println("Start work for " + name + " !");

}

});

// // lambda 表达式设置监听器

// myService.setWorkListener(name -> System.out.println("Start work for " + name + " !"));

// 工作

myService.work("boss");

}

@Test

public void test2() {

// 继承实现类设置监听器

myService.setWorkListener(new myWorkListener());

// 工作

myService.work("boss");

}

class myWorkListener extends WorkListenerAdaptor {

@Override

public void onStart(String name) {

System.out.println("Start work for " + name + " !");

}

}

}

使用以上两种方法测试,得到了结果为:

Start work for boss !

working hard ...

说明在动作work发生之前,执行了我们在测试类中写下的监听代码,实现类监听的目的。

使用注解实现监听器

在以上代码中,调用 setWorkListener(WorkListener listener)  方法一般称作设置(注册)监听器,就是将自己写好的监听代码,设置为动作的监听器。然而,在每次注册监听器时,一般需要写一个类,实现定义好的接口或继承实现接口的类,再重写接口定义的方法即可。因此,聪明的程序员就想简化这个过程,所以就想出了使用注解的方法。使用注解,将监听代码段写在一个方法中,使用一个注解标记这个方法即可。

的确,使用变得简单了,但实现却不见得。

1. 定义一个注解

package com.yawn.demo.anno;

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

public @interface WorkListener {

}

2. 解析注解

package com.yawn.demo.anno;

import com.yawn.demo.service.MyService;

import org.springframework.beans.BeansException;

import org.springframework.beans.factory.InitializingBean;

import org.springframework.context.ApplicationContext;

import org.springframework.context.ApplicationContextAware;

import org.springframework.stereotype.Component;

import javax.annotation.Resource;

import java.lang.annotation.Annotation;

import java.lang.reflect.Method;

import javaBhrQRvMkOJ.util.LinkedHashMap;

import java.util.Map;

/**

* @author Created by yawn on 2018-01-21 14:46

*/

@Component

public class WorkListenerParser implements ApplicationContextAware, InitializingBean {

@Resource

private MyService myService;

private ApplicationContext applicationContext;

@Override

public void afterPropertiesSet() throws Exception {

Map listenerBeans = getExpectListenerBeans(Controller.class, RestController.class, Service.class, Component.class);

for (Object listener : listenerBeans.values()) {

for (Method method : listener.getClass().getDeclaredMethods()) {

if (!method.isAnnotationPresent(WorkListener.class)) {

continue;

}

myService.setWorkListener(name -> {

try {

method.invoke(listener, name);

} catch (Exception e) {

e.printStackTrace();

}

});

}

}

}

/**

* 找到有可能使用注解的bean

* @param annotationTypes 需要进行扫描的类级注解类型

* @return 扫描到的beans的map

*/

private Map getExpectListenerBeans(Class extends Annotation>... annota

在注解的解析过程中,设置监听器。

在解析类中,实现了接口ApplicationContextAware,为了在类中拿到ApplicationContext的引用,用于得到 IOC 容器中的 Bean;而实现接口InitializingBean,则是为了在一个合适的时机执行解析注解、设置监听器的代码。 如果不这样做,www.cppcns.com可以在CommandLineRunner执行时调用解析、设置的代码,而ApplicationContext也可以自动注入。

3. 测试

在执行完以上代码后,监听器就已经设置好了,可以进行测试了。

package com.yawn.demo.controller;

import com.yawn.demo.anno.WorkListener;

import com.yawn.demo.service.MyService;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**

* @author Created by yawn on 2018-01-21 13:28

*/

@RestController

public class TestController {

@Resource

private MyService myService;

@GetMapping("/work")

public Object work() {

myService.work("boss");

return "done";

}

@WorkListener

public void listen(String name) {

System.out.println("Start work for " + name + " !");

}

}

写一个监听方法,参数类型和个数与接口相同,然后加上自定义的注解即可。当启动环境后,监听器就已经设置好了。

然后通过url调用myService的work()方法,可以看到结果:

Start work for boss !

www.cppcns.comworking hard ...

已经调用了监听方法。在接下来的开发中,就可以使用这个注解注册监听器了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

本文标题: 在spring中使用自定义注解注册监听器的方法

本文地址: http://www.cppcns.com/ruanjian/java/218391.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值