小編給大家分享一下在spring中如何使用自定義注解注冊監(jiān)聽器,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長期合作伙伴,公司提供的服務(wù)項(xiàng)目有:域名申請、雅安服務(wù)器托管、營銷軟件、網(wǎng)站建設(shè)、新巴爾虎右網(wǎng)站維護(hù)、網(wǎng)站推廣。
接口回調(diào)
監(jiān)聽器本質(zhì)上就是利用回調(diào)機(jī)制,在某個(gè)動(dòng)作發(fā)生前或后,執(zhí)行我們自己的一些代碼。在Java語言中,可以使用接口來實(shí)現(xiàn)。
實(shí)現(xiàn)一個(gè)監(jiān)聽器案例
為了方便,直接在spring環(huán)境中定義:以工作(work)為例,定義工作開始時(shí)(或結(jié)束時(shí))的監(jiān)聽器。
1. 定義回調(diào)的接口
package com.yawn.demo.listener;
/**
* @author Created by yawn on 2018-01-21 13:53
*/
public interface WorkListener {
void onStart(String name);
}2. 定義動(dòng)作
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();
}
}動(dòng)作work為一個(gè)具體的方法,在work()方法的適當(dāng)時(shí)機(jī),調(diào)用前面定義的接口。此外,在這個(gè)動(dòng)作定義類中,需要提高設(shè)置監(jiān)聽器的方法。
3. 監(jiān)聽測試
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoSpringAnnotationApplicationTests {
@Resource
private MyService myService;
@Test
public void test1() {
// 接口設(shè)置監(jiān)聽器
myService.setWorkListener(new WorkListener() {
@Override
public void onStart(String name) {
System.out.println("Start work for " + name + " !");
}
});
// // lambda 表達(dá)式設(shè)置監(jiān)聽器
// myService.setWorkListener(name -> System.out.println("Start work for " + name + " !"));
// 工作
myService.work("boss");
}
@Test
public void test2() {
// 繼承實(shí)現(xiàn)類設(shè)置監(jiān)聽器
myService.setWorkListener(new myWorkListener());
// 工作
myService.work("boss");
}
class myWorkListener extends WorkListenerAdaptor {
@Override
public void onStart(String name) {
System.out.println("Start work for " + name + " !");
}
}
}使用以上兩種方法測試,得到了結(jié)果為:
Start work for boss ! working hard ...
說明在動(dòng)作work發(fā)生之前,執(zhí)行了我們在測試類中寫下的監(jiān)聽代碼,實(shí)現(xiàn)類監(jiān)聽的目的。
使用注解實(shí)現(xiàn)監(jiān)聽器
在以上代碼中,調(diào)用 setWorkListener(WorkListener listener) 方法一般稱作設(shè)置(注冊)監(jiān)聽器,就是將自己寫好的監(jiān)聽代碼,設(shè)置為動(dòng)作的監(jiān)聽器。然而,在每次注冊監(jiān)聽器時(shí),一般需要寫一個(gè)類,實(shí)現(xiàn)定義好的接口或繼承實(shí)現(xiàn)接口的類,再重寫接口定義的方法即可。因此,聰明的程序員就想簡化這個(gè)過程,所以就想出了使用注解的方法。使用注解,將監(jiān)聽代碼段寫在一個(gè)方法中,使用一個(gè)注解標(biāo)記這個(gè)方法即可。
的確,使用變得簡單了,但實(shí)現(xiàn)卻不見得。
1. 定義一個(gè)注解
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 java.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<String, Object> 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 需要進(jìn)行掃描的類級(jí)注解類型
* @return 掃描到的beans的map
*/
private Map<String, Object> getExpectListenerBeans(Class<? extends Annotation>... annotationTypes) {
Map<String, Object> listenerBeans = new LinkedHashMap<>();
for (Class<? extends Annotation> annotationType : annotationTypes) {
Map<String, Object> annotatedBeansMap = applicationContext.getBeansWithAnnotation(annotationType);
listenerBeans.putAll(annotatedBeansMap);
}
return listenerBeans;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}在注解的解析過程中,設(shè)置監(jiān)聽器。
在解析類中,實(shí)現(xiàn)了接口ApplicationContextAware,為了在類中拿到ApplicationContext的引用,用于得到 IOC 容器中的 Bean;而實(shí)現(xiàn)接口InitializingBean,則是為了在一個(gè)合適的時(shí)機(jī)執(zhí)行解析注解、設(shè)置監(jiān)聽器的代碼。 如果不這樣做,可以在CommandLineRunner執(zhí)行時(shí)調(diào)用解析、設(shè)置的代碼,而ApplicationContext也可以自動(dòng)注入。
3. 測試
在執(zhí)行完以上代碼后,監(jiān)聽器就已經(jīng)設(shè)置好了,可以進(jìn)行測試了。
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 + " !");
}
}寫一個(gè)監(jiān)聽方法,參數(shù)類型和個(gè)數(shù)與接口相同,然后加上自定義的注解即可。當(dāng)啟動(dòng)環(huán)境后,監(jiān)聽器就已經(jīng)設(shè)置好了。
然后通過url調(diào)用myService的work()方法,可以看到結(jié)果:
Start work for boss ! working hard ...
已經(jīng)調(diào)用了監(jiān)聽方法。在接下來的開發(fā)中,就可以使用這個(gè)注解注冊監(jiān)聽器了。
看完了這篇文章,相信你對“在spring中如何使用自定義注解注冊監(jiān)聽器”有了一定的了解,如果想了解更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!
網(wǎng)站標(biāo)題:在spring中如何使用自定義注解注冊監(jiān)聽器
轉(zhuǎn)載來源:http://chinadenli.net/article0/gphioo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)網(wǎng)站制作、搜索引擎優(yōu)化、電子商務(wù)、域名注冊、網(wǎng)站維護(hù)、網(wǎng)站設(shè)計(jì)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)