[Java]-Spring中事件EventListener与Guava

ApplicationEventListener是Spring中的一个事件监听、订阅实现(实现原理是观察者设计模式),为了系统业务逻辑之间的解耦,提高可扩展性以及可维护性。

事件

spring事件由三部分组成:事件(ApplicationEvent)、监听器(ApplicationListener)和事件发布操作。

ApplicationEvent

所有要发布的事件都需要继承ApplicationEvent。

public class CreateMsgEvent extends ApplicationEvent {
    public CreateMsgEvent(Object source) {
        super(source);
    }

    public MsgEventData getMsg(){
        Preconditions.checkState(source!=null);
        return (MsgEventData)this.source;
    }
}

@Data
public class MsgEventData {
    private String msg;
}

@EventListener

@EventListener是在spring4.2中引入的,可替代早期的ApplicationListener接口,实现事件侦听。

@Service
public class EventListener {
    private static final Logger _logger = LoggerFactory.getLogger(EventListener.class);

    @org.springframework.context.event.EventListener
    public void onSynMsgEvent(CreateMsgEvent event){
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        _logger.info("onSynMsgEvent: {}", event);
    }

    @Async
    @org.springframework.context.event.EventListener
    public void onAsynMsgEvent(CreateMsgEvent event){
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        _logger.info("onAsynMsgEvent: {}", event);
    }
}

默认情况下,侦听是同步的,即只有侦听函数处理完成返回后;发布事件的接口才会返回。通过增加@Async注解可实现异步侦听。

@Async

springboot中@EnableAsync与@Async注解配合使用,即可实现异步调用:

  • 在方法上标注@Async注解,指示该方法需加入线程池以实现异步运行;
  • 需要@EnableAsync配合使用,异步才生效:若未启用异步,则@Async不启作用。

在启动类上标注@EnableAsync注解,以启用@Async异步注解:

@EnableAsync
@SpringBootApplication
public class StudyApplication extends SpringBootServletInitializer {

	public static void main(String[] args) {
		SpringApplication.run(StudyApplication.class, args);
	}

}

发布

ApplicationEventPublisher把事件发布给每个侦听器:

  • 同步侦听:只有侦听器执行完返回后,publishEvent才完成;
  • 异步侦听:发布后即可返回;
@RestController
@RequestMapping("test")
public class TestController {
    private static final Logger _logger = LoggerFactory.getLogger(TestController.class);

    @Autowired
    ApplicationEventPublisher publisher;

    @GetMapping("testEvent")
    public String testEvent(HttpServletRequest request, String msg){
        MsgEventData msgData = new MsgEventData();
        msgData.setMsg(msg);
        _logger.info("To publish");
        publisher.publishEvent(new CreateMsgEvent(msgData));
        _logger.info("Published");
        return msg;
    }
}

发布给以上一个同步、一个异步侦听器后输出结果为:

To publish
>>onSynMsgEvent
onSynMsgEvent: [source=MsgEventData(msg=safs)]
Published
>>onAsynMsgEvent
onAsynMsgEvent: [source=MsgEventData(msg=safs)]

guava

Guava工程包含了若干被Google的 Java项目广泛依赖 的核心库,例如:集合 [collections] 、缓存 [caching] 、原生类型支持 [primitives support] 、并发库 [concurrency libraries] 、通用注解 [common annotations] 、字符串处理 [string processing] 、I/O 等等。

Preconditions

Preconditions 提供了判断条件是否合法的静态方法,如果不符合要求会抛出异常(类似断言)。

方法声明描述检查失败时抛出的异常
checkArgument(boolean)检查boolean是否为true,用来检查传递给方法的参数IllegalArgumentException
checkNotNull(T)检查value是否为null,该方法直接返回value,因此可以内嵌使用checkNotNullNullPointerException
checkState(boolean)用来检查对象的某些状态。IllegalStateException
checkElementIndex(int index, int size)检查index作为索引值对某个列表、字符串或数组是否有效。index>=0 && index<sizeIndexOutOfBoundsException
checkPositionIndex(int index, int size)检查index作为位置值对某个列表、字符串或数组是否有效。index>=0 && index<=sizeIndexOutOfBoundsException
checkPositionIndexes(int start, int end, int size)检查[start, end]表示的位置范围对某个列表、字符串或数组是否有效IndexOutOfBoundsException

Jointer

用分隔符将多个**字符串(或数组元素)**连接成一个字符串:

  1. on(String):静态工厂方法,生成一个新的 Joiner 对象,参数为连接符;
  2. skipNulls():如果元素为空,则跳过;
  3. useForNull(String):如果元素为空,则用这个字符串代替;
  4. join(数组/链表):要连接的数组/链表;
  5. appendTo(String,数组/链表):在第一个参数后面新加上 拼接后的字符串;
  6. withKeyValueSeparator(String):得到 MapJoiner,Map键、值的连接符;
    @GetMapping("testGuava")
    public void testGuava(){
        List<String> lstTest = Arrays.asList("aa", "bb", "cc", null, "dd");
        System.out.println(Joiner.on("; ").useForNull("<null>").join(lstTest)); // aa; bb; cc; <null>; dd

        Map map = ImmutableMap.of("k1", "v1", "k2", "v2");
        System.out.println(Joiner.on("; ").withKeyValueSeparator("=").join(map)); // k1=v1; k2=v2
    }

Splitter

Splitter 将一个字符串按照分隔符生成字符串集合:

  1. on(String):静态工厂方法,生成一个新的 Splitter 对象,参数为分隔符;
  2. trimResults():结果去除子串中的空格;
  3. omitEmptyStrings():去除空子串;
  4. split(String):拆分字符串;
  5. withKeyValueSeparator(String):得到 MapSplitter,拆分成Map的键、值。注意,这个对被拆分字符串格式有严格要求,否则会抛出异常
String strList = "aa; bb; cc; <null>; dd";
System.out.println(Splitter.on(";").trimResults().split(strList)); // [aa, bb, cc, <null>, dd]

String strMap = "k1=v1; k2=v2";
System.out.println(Splitter.on(";").trimResults().withKeyValueSeparator("=").split(strMap)); // {k1=v1, k2=v2}

Strings

Strings 类主要提供了对字符串的一些操作:

  1. nullToEmpty(String string) :null字符串转空字符串;
  2. emptyToNull(String string):空字符串转null字符串;
  3. isNullOrEmpty(String string):判断字符串为null或空字符串;
  4. padStart(String string, int minLength, char padChar):如果string的长度小于minLeng,在string前添加padChar,直到字符串长度为minLeng。

集合

可变集合接口JDK/Guava不可变版本
CollectionJDKImmutableCollection
ListJDKImmutableList
SetJDKImmutableSet
SortedSet/NavigableSetJDKImmutableSortedSet
MapJDKImmutableMap
SortedMapJDKImmutableSortedMap
MultisetGuavaImmutableMultiset
SortedMultisetGuavaImmutableSortedMultiset
MultimapGuavaImmutableMultimap
ListMultimapGuavaImmutableListMultimap
SetMultimapGuavaImmutableSetMultimap
BiMapGuavaImmutableBiMap
ClassToInstanceMapGuavaImmutableClassToInstanceMap
TableGuavaImmutableTable
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值