欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring事件監(jiān)聽(tīng)機(jī)制觀察者模式詳解

 更新時(shí)間:2022年11月16日 14:05:57   作者:程序新視界  
這篇文章主要為大家介紹了Spring事件監(jiān)聽(tīng)機(jī)制觀察者模式實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

Spring中提供了一套默認(rèn)的事件監(jiān)聽(tīng)機(jī)制,在容器初始化時(shí)便使用了這套機(jī)制。同時(shí),Spring也提供了事件監(jiān)聽(tīng)機(jī)制的接口擴(kuò)展能力,開(kāi)發(fā)者基于此可快速實(shí)現(xiàn)自定義的事件監(jiān)聽(tīng)功能。

Spring的事件監(jiān)聽(tīng)機(jī)制是在JDK事件監(jiān)聽(tīng)的基礎(chǔ)上進(jìn)行的擴(kuò)展,也是在典型觀察者模式上的進(jìn)一步抽象和改進(jìn)。所以,結(jié)合Spring的事件監(jiān)聽(tīng)機(jī)制與觀察者模式來(lái)學(xué)習(xí),可以達(dá)到理論與實(shí)踐的完美融合。

本篇文章就以觀察者模式和Spring事件監(jiān)聽(tīng)機(jī)制作為切入點(diǎn),結(jié)合具體的實(shí)例來(lái)對(duì)兩者進(jìn)行系統(tǒng)的學(xué)習(xí)和實(shí)踐。

觀察者模式

觀察者模式(Observer Pattern),也叫作發(fā)布-訂閱模式(Publish/Subscribe)。

無(wú)論是觀察者模式,還是Spring的事件監(jiān)聽(tīng)機(jī)制,本質(zhì)上都是在定義對(duì)象間一對(duì)多的依賴關(guān)系,使得每當(dāng)一個(gè)對(duì)象(被觀察者/事件)改變狀態(tài)時(shí),所有依賴于它的對(duì)象(觀察者/事件監(jiān)聽(tīng)器)都會(huì)得到通知,并被自動(dòng)更新。

觀察者模式的優(yōu)點(diǎn)在于:觀察者和被觀察者之間是抽象耦合,不管是新增觀察者或是被觀察者,都非常容易擴(kuò)展。這也符合面向?qū)ο笏珜?dǎo)的“開(kāi)閉原則”:對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉

觀察者模式適用于以下三類場(chǎng)景:

  • 關(guān)聯(lián)行為場(chǎng)景,而且關(guān)聯(lián)是可拆分的。
  • 事件多級(jí)觸發(fā)場(chǎng)景。
  • 跨系統(tǒng)的消息交換場(chǎng)景,比如消息隊(duì)列的處理機(jī)制。

在使用的過(guò)程中,也要綜合考慮開(kāi)發(fā)效率和運(yùn)行效率的問(wèn)題。通常,一個(gè)被觀察者會(huì)對(duì)應(yīng)多個(gè)觀察者,那么在開(kāi)發(fā)和調(diào)試的過(guò)程中會(huì)有一定的復(fù)雜度。

同時(shí),因?yàn)楸挥^察者存在關(guān)聯(lián)、多級(jí)拆分,也就是會(huì)有多個(gè)觀察者,而Java消息的通知(和Spring的事件監(jiān)聽(tīng)機(jī)制)默認(rèn)是順序執(zhí)行的,如果其中一個(gè)觀察者執(zhí)行時(shí)間過(guò)長(zhǎng)或卡死,勢(shì)必會(huì)影響整體的效率。此時(shí),就需要考慮異步處理。

觀察者的角色定義

觀察者模式是一個(gè)典型的發(fā)布-訂閱模型,其中主要涉及四個(gè)角色:

  • 抽象被觀察者角色:內(nèi)部持有所有觀察者角色的引用,并對(duì)外提供新增、移除觀察者角色、通知所有觀察者的功能;
  • 具體被觀察者角色:當(dāng)狀態(tài)變更時(shí),會(huì)通知到所有的觀察者角色;
  • 抽象觀察者角色:抽象具體觀察者角色的一些共性方法,如狀態(tài)變更方法;
  • 具體觀察者角色:實(shí)現(xiàn)抽象觀察者角色的方法;

UML類圖展示類觀察者模式大體如下:

以具體的代碼來(lái)展示一下觀察者模式的實(shí)現(xiàn)。

第一,定義抽象觀察者。

/**
 * 抽象觀察者角色
 * @author sec
 **/
public abstract class AbstractObserver {
  /**
   * 接收消息
   * @param context 消息內(nèi)容
   */
  public abstract void receiveMsg(String context);
}

第二,定義抽象被觀察者。

/**
 * 抽象主題(抽象被觀察者角色)
 * @author sec
 **/
public abstract class AbstractSubject {
  /**
   * 持有所有抽象觀察者角色的集合引用
   */
  private final List<AbstractObserver> observers = new ArrayList<>();
  /**
   * 添加一個(gè)觀察者
   * @param observer 觀察者
   */
  public void addObserver(AbstractObserver observer){
    observers.add(observer);
  }
  /**
   * 移除一個(gè)觀察者
   * @param observer 觀察者
   */
  public void removeObserver(AbstractObserver observer){
    observers.remove(observer);
  }
  /**
   * 通知所有的觀察者,執(zhí)行觀察者更新方法
   * @param context 通知內(nèi)容
   */
  public void notifyObserver(String context){
    observers.forEach(observer -> observer.receiveMsg(context));
  }
}

第三,定義具體被觀察者,實(shí)現(xiàn)了抽象被觀察者。

/**
 * 具體被觀察者
 * @author sec
 **/
public class ConcreteSubject extends AbstractSubject{
  /**
   * 被觀察者發(fā)送消息
   * @param context 消息內(nèi)容
   */
  public void sendMsg(String context){
    System.out.println("具體被觀察者角色發(fā)送消息: " + context);
    super.notifyObserver(context);
  }
}

第四,定義具體觀察者,實(shí)現(xiàn)了抽象觀察者。

/**
 * 具體觀察者角色實(shí)現(xiàn)類
 * @author sec
 **/
public class ConcreteObserver extends AbstractObserver{
  @Override
  public void receiveMsg(String context) {
    System.out.println("具體觀察者角色接收消息: " + context);
  }
}

第五,使用演示類。

public class ObserverPatternTest {
  public static void main(String[] args) {
    ConcreteSubject subject = new ConcreteSubject();
    subject.addObserver(new ConcreteObserver());
    subject.sendMsg("Hello World!");
  }
}

執(zhí)行上述方法,控制臺(tái)打印日志為:

具體被觀察者角色發(fā)送消息: Hello World!
具體觀察者角色接收消息: Hello World!

在上述代碼實(shí)現(xiàn)中,被觀察者發(fā)出消息后,觀察者接收到具體的消息,如果添加了多個(gè)觀察者,它們均會(huì)收到消息。也就是前面所說(shuō)的,每當(dāng)一個(gè)對(duì)象(被觀察者/事件)改變狀態(tài)時(shí),所有依賴于它的對(duì)象(觀察者/事件監(jiān)聽(tīng)器)都會(huì)得到通知,并被自動(dòng)更新。

Java中的事件機(jī)制

前面聊了觀察者模式,這里再來(lái)看看Java中的事件機(jī)制。

在JDK 1.1及以后版本中,事件處理模型采用基于觀察者模式的委派事件模型(DelegationEvent Model, DEM),即一個(gè)Java組件所引發(fā)的事件并不由引發(fā)事件的對(duì)象自己來(lái)負(fù)責(zé)處理,而是委派給獨(dú)立的事件處理對(duì)象負(fù)責(zé)。

這并不是說(shuō)事件模型是基于Observer和Observable的,事件模型與Observer和Observable沒(méi)有任何關(guān)系,Observer和Observable只是觀察者模式的一種實(shí)現(xiàn)而已。

Java中的事件機(jī)制有三個(gè)角色參與:

Event Source:事件源,發(fā)起事件的主體。

Event Object:事件狀態(tài)對(duì)象,傳遞的信息載體,可以是事件源本身,一般作為參數(shù)存在于listerner的方法之中。所有事件狀態(tài)對(duì)象都將從Java中的EventObject派生而來(lái);

Event Listener:事件監(jiān)聽(tīng)器,當(dāng)監(jiān)聽(tīng)到EventObject產(chǎn)生時(shí),調(diào)用相應(yīng)的方法進(jìn)行處理。所有事件偵 聽(tīng) 器接口必須擴(kuò)展EventListener接口;

UML類圖展示類事件模式大體如下:

在上面的UML圖中,EventObject一般作為L(zhǎng)istener處理方法的參數(shù)傳入,而EventSource是事件的觸發(fā)者,通過(guò)此對(duì)象注冊(cè)相關(guān)的Listener,然后向Listener觸發(fā)事件。

通過(guò)UML圖的對(duì)比可以看出,事件監(jiān)聽(tīng)模式和觀察者模式大同小異,它們屬于同一類型模式,都屬于回調(diào)機(jī)制,主動(dòng)推送消息,但在使用場(chǎng)景上有所區(qū)別。

觀察者(Observer)相當(dāng)于事件監(jiān)聽(tīng)者(監(jiān)聽(tīng)器),被觀察者(Observable)相當(dāng)于事件源和事件,事件監(jiān)聽(tīng)比觀察者模式要復(fù)雜一些,多了EventSource角色的存在。

以具體的代碼來(lái)展示一下Java中的事件機(jī)制實(shí)現(xiàn)。

第一,定義事件對(duì)象。

/**
 * 事件對(duì)象
 *
 * @author sec
 **/
public class DoorEvent extends EventObject {
  private int state;
  /**
   * Constructs a prototypical Event.
   *
   * @param source The object on which the Event initially occurred.
   * @throws IllegalArgumentException if source is null.
   */
  public DoorEvent(Object source) {
    super(source);
  }
  public DoorEvent(Object source, int state) {
    super(source);
    this.state = state;
  }
  // 省略getter/setter方法 
}

第二,定義事件監(jiān)聽(tīng)器接口。

/**
 * 事件監(jiān)聽(tīng)器接口
 *
 * @author sec
 **/
public interface DoorListener extends EventListener {
  /**
   * 門處理事件
   * @param doorEvent 事件
   */
  void doorEvent(DoorEvent doorEvent);
}

第三,定義事件監(jiān)聽(tīng)器的實(shí)現(xiàn)類。

public class CloseDoorListener implements DoorListener{
  @Override
  public void doorEvent(DoorEvent doorEvent) {
    if(doorEvent.getState() == -1){
      System.out.println("門關(guān)上了");
    }
  }
}
public class OpenDoorListener implements DoorListener{
  @Override
  public void doorEvent(DoorEvent doorEvent) {
    if(doorEvent.getState() == 1){
      System.out.println("門打開(kāi)了");
    }
  }
}

這里實(shí)現(xiàn)了門的開(kāi)和關(guān)兩個(gè)事件監(jiān)聽(tīng)器類。

第四,定義事件源EventSource。

public class EventSource {
  //監(jiān)聽(tīng)器列表,監(jiān)聽(tīng)器的注冊(cè)則加入此列表
  private Vector<DoorListener> listenerList = new Vector<>();
  //注冊(cè)監(jiān)聽(tīng)器
  public void addListener(DoorListener eventListener) {
    listenerList.add(eventListener);
  }
  //撤銷注冊(cè)
  public void removeListener(DoorListener eventListener) {
    listenerList.remove(eventListener);
  }
  //接受外部事件
  public void notifyListenerEvents(DoorEvent event) {
    for (DoorListener eventListener : listenerList) {
      eventListener.doorEvent(event);
    }
  }
}

第五,測(cè)試類。

public class EventTest {
  public static void main(String[] args) {
    EventSource eventSource = new EventSource();
    eventSource.addListener(new CloseDoorListener());
    eventSource.addListener(new OpenDoorListener());
    eventSource.notifyListenerEvents(new DoorEvent("關(guān)門事件", -1));
    eventSource.notifyListenerEvents(new DoorEvent("開(kāi)門時(shí)間", 1));
  }
}

執(zhí)行測(cè)試類,控制臺(tái)打?。?/p>

門關(guān)上了
門打開(kāi)了

事件成功觸發(fā)。

Spring中的事件機(jī)制

在了解了觀察者模式和Java的事件機(jī)制之后,再來(lái)看看Spring中的事件機(jī)制。在Spring容器中,通過(guò)ApplicationEventApplicationListener接口來(lái)實(shí)現(xiàn)事件監(jiān)聽(tīng)機(jī)制。每次Event事件被發(fā)布到Spring容器中,都會(huì)通知對(duì)應(yīng)的Listener。默認(rèn)情況下,Spring的事件監(jiān)聽(tīng)機(jī)制是同步的。

Spring的事件監(jiān)聽(tīng)由三部分組成:

  • 事件(ApplicationEvent): 該類繼承自JDK中的EventObject,負(fù)責(zé)對(duì)應(yīng)相應(yīng)的監(jiān)聽(tīng)器,事件源發(fā)生某事件是特定事件監(jiān)聽(tīng)器被觸發(fā)的原因;
  • 監(jiān)聽(tīng)器(ApplicationListener):該類繼承自JDK中的EventListener,對(duì)應(yīng)于觀察者模式中的觀察者。監(jiān)聽(tīng)器監(jiān)聽(tīng)特定事件,并在內(nèi)部定義了事件發(fā)生后的響應(yīng)邏輯;
  • 事件發(fā)布器(ApplicationEventPublisher):對(duì)應(yīng)于觀察者模式中的被觀察者/主題,負(fù)責(zé)通知觀察者,對(duì)外提供發(fā)布事件和增刪事件監(jiān)聽(tīng)器的接口,維護(hù)事件和事件監(jiān)聽(tīng)器之間的映射關(guān)系,并在事件發(fā)生時(shí)負(fù)責(zé)通知相關(guān)監(jiān)聽(tīng)器。

通過(guò)上面的分析可以看出Spring的事件機(jī)制不僅是觀察者模式的一種實(shí)現(xiàn),也實(shí)現(xiàn)了JDK提供的事件接口。同時(shí),除了發(fā)布者和監(jiān)聽(tīng)者之外,還存在一個(gè)EventMulticaster的角色,負(fù)責(zé)把事件轉(zhuǎn)發(fā)給監(jiān)聽(tīng)者。

Spring事件機(jī)制的工作流程如下:

在上述流程中,發(fā)布者調(diào)用applicationEventPublisher.publishEvent(msg),將事件發(fā)送給EventMultiCaster。EventMultiCaster注冊(cè)著所有的Listener,它會(huì)根據(jù)事件類型決定轉(zhuǎn)發(fā)給那個(gè)Listener。

在Spring中提供了一些標(biāo)準(zhǔn)的事件,比如:ContextRefreshEvent、ContextStartedEvent、ContextStoppedEvent、ContextClosedEvent、RequestHandledEvent等。

關(guān)于Spring事件機(jī)制的具體實(shí)現(xiàn)和這些標(biāo)準(zhǔn)事件的作用,大家可以通過(guò)閱讀源碼來(lái)學(xué)習(xí),這里不再詳細(xì)展開(kāi)。

下面來(lái)看看Spring事件機(jī)制涉及到的幾個(gè)角色的源碼及后續(xù)基于它們的實(shí)踐。

第一,事件(ApplicationEvent)。

public abstract class ApplicationEvent extends EventObject {
  /** use serialVersionUID from Spring 1.2 for interoperability. */
  private static final long serialVersionUID = 7099057708183571937L;
  /** System time when the event happened. */
  private final long timestamp;
  /**
   * Create a new {@code ApplicationEvent}.
   * @param source the object on which the event initially occurred or with
   * which the event is associated (never {@code null})
   */
  public ApplicationEvent(Object source) {
    super(source);
    this.timestamp = System.currentTimeMillis();
  }
  /**
   * Return the system time in milliseconds when the event occurred.
   */
  public final long getTimestamp() {
    return this.timestamp;
  }
}

事件可類比觀察者中的被觀察者實(shí)現(xiàn)類的角色,繼承自JDK的EventObject。上述Spring中的標(biāo)準(zhǔn)事件都是直接或間接繼承自該類。

第二,事件發(fā)布器(ApplicationEventPublisher)。

@FunctionalInterface
public interface ApplicationEventPublisher {
  default void publishEvent(ApplicationEvent event) {
    publishEvent((Object) event);
  }
  void publishEvent(Object event);
}

通過(guò)實(shí)現(xiàn)ApplicationEventPublisher接口,并重寫publishEvent()方法,可以自定義事件發(fā)布的邏輯。ApplicationContext繼承了ApplicationEventPublisher接口。因此,我們可以通過(guò)實(shí)現(xiàn)ApplicationContextAware接口,注入ApplicationContext,然后通過(guò)ApplicationContext的publishEvent()方法來(lái)實(shí)現(xiàn)事件發(fā)布功能。

ApplicationContext容器本身僅僅是對(duì)外提供了事件發(fā)布的接口publishEvent(),真正的工作委托給了具體容器內(nèi)部的ApplicationEventMulticaster對(duì)象。而ApplicationEventMulticaster對(duì)象可類比觀察者模式中的抽象被觀察者角色,負(fù)責(zé)持有所有觀察者集合的引用、動(dòng)態(tài)添加、移除觀察者角色。

第三,事件監(jiān)聽(tīng)器(ApplicationListener)。

@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
  /**
   * Handle an application event.
   * @param event the event to respond to
   */
  void onApplicationEvent(E event);
}

事件監(jiān)聽(tīng)器(ApplicationListener)對(duì)應(yīng)于觀察者模式中的具體觀察者角色。當(dāng)事件發(fā)布之后,就會(huì)執(zhí)行事件監(jiān)聽(tīng)器的邏輯。通過(guò)實(shí)現(xiàn)ApplicationListener接口,并重寫onApplicationEvent()方法,就可以監(jiān)聽(tīng)到事件發(fā)布器發(fā)布的事件。

Spring事件監(jiān)聽(tīng)案例

下面以具體的案例代碼來(lái)說(shuō)明如何自定義實(shí)現(xiàn)Spring事件監(jiān)聽(tīng)。

第一,自定義定義事件對(duì)象,集成自ApplicationEvent。

public class MyEvent extends ApplicationEvent {
  /**
   * Create a new {@code ApplicationEvent}.
   *
   * @param source the object on which the event initially occurred or with
   *               which the event is associated (never {@code null})
   */
  public MyEvent(Object source) {
    super(source);
  }
  private String context;
  public MyEvent(Object source, String context){
    super(source);
    this.context = context;
  }
  public String getContext() {
    return context;
  }
  public void setContext(String context) {
    this.context = context;
  }
}

第二,自定義ApplicationListener事件監(jiān)聽(tīng)器。

@Component
public class MyApplicationListener implements ApplicationListener<MyEvent> {
  @Override
  public void onApplicationEvent(MyEvent event) {
    // 監(jiān)聽(tīng)到具體事件,處理對(duì)應(yīng)具體邏輯
    System.out.println("event.getContext() = " + event.getContext());
  }
}

除了上述基于實(shí)現(xiàn)ApplicationListener接口的方式外,還可以使用 @EventListener注解來(lái)實(shí)現(xiàn),實(shí)現(xiàn)示例如下:

@Component
public class MyApplicationListener{
    // 通過(guò)注解實(shí)現(xiàn)監(jiān)聽(tīng)器
    @EventListener
    public void handleMyEvent(MyEvent event){
        // 監(jiān)聽(tīng)到具體事件,處理對(duì)應(yīng)具體邏輯
        System.out.println("event.getContext() = " + event.getContext());
    }
}

第三,使用及單元測(cè)試。

@Slf4j
@SpringBootTest
public class SpringEventTest {
  @Autowired
  private ApplicationEventPublisher eventPublisher;
  @Test
  void testEvent() {
    eventPublisher.publishEvent(new MyEvent("自定義事件", "Hello World!"));
  }
}

執(zhí)行單元測(cè)試,可看到控制臺(tái)打印對(duì)應(yīng)的事件信息。

通過(guò)上述方式我們已經(jīng)成功實(shí)現(xiàn)了基于Spring的事件監(jiān)聽(tīng)機(jī)制,但這其中還有一個(gè)問(wèn)題:同步處理。默認(rèn)情況下,上述事件是基于同步處理的,如果其中一個(gè)監(jiān)聽(tīng)器阻塞,那么整個(gè)線程將處于等待狀態(tài)。

那么,如何使用異步方式處理監(jiān)聽(tīng)事件呢?只需兩步即可。

第一步,在監(jiān)聽(tīng)器類或方法上添加@Async注解,例如:

@Component
@Async
public class MyApplicationListener implements ApplicationListener<MyEvent> {
  @Override
  public void onApplicationEvent(MyEvent event) {
    // 監(jiān)聽(tīng)到具體事件,處理對(duì)應(yīng)具體邏輯
    System.out.println("event.getContext() = " + event.getContext());
  }
}

第二步,在SpringBoot啟動(dòng)類(這里以SpringBoot項(xiàng)目為例)上添加@EnableAsync注解,例如:

@SpringBootApplication
@EnableAsync
public class SpringBootMainApplication {
  public static void main(String[] args) {
    SpringApplication.run(SpringBootMainApplication.class, args);
  }
}

此時(shí),就可以實(shí)現(xiàn)異步監(jiān)聽(tīng)功能了。當(dāng)然,@Async注解也可以指定我們已經(jīng)配置好的線程池來(lái)處理異步請(qǐng)求,關(guān)于線程數(shù)的初始化這里就不再演示了。

小結(jié)

本篇文章帶大家從觀察者模式、Java事件機(jī)制延伸到Spring的事件監(jiān)聽(tīng)機(jī)制,將三者融合在一起來(lái)講解。通過(guò)這個(gè)案例,其實(shí)我們能夠體會(huì)到一些經(jīng)驗(yàn)性的知識(shí),比如看似復(fù)雜的Spring事件監(jiān)聽(tīng)機(jī)制實(shí)現(xiàn)只不過(guò)是觀察者模式的一種實(shí)現(xiàn),而其中又集成了Java的事件機(jī)制。這也就是所謂的融會(huì)貫通。

我們?nèi)绻麊渭兊膶W(xué)習(xí)某一個(gè)設(shè)計(jì)模式,可能只會(huì)運(yùn)用和識(shí)別它的簡(jiǎn)單實(shí)現(xiàn),而實(shí)踐中往往會(huì)對(duì)設(shè)計(jì)模式進(jìn)行變種,甚至融合多種設(shè)計(jì)模式的優(yōu)點(diǎn)于一體,這便是活學(xué)活用。希望通過(guò)這邊文章你能夠更加深入的理解上述三者。

以上就是Spring事件監(jiān)聽(tīng)機(jī)制觀察者模式詳解的詳細(xì)內(nèi)容,更多關(guān)于Spring事件監(jiān)聽(tīng)觀察者模式的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 關(guān)于文件上傳MultipartBody的使用方法

    關(guān)于文件上傳MultipartBody的使用方法

    這篇文章主要介紹了關(guān)于文件上傳MultipartBody的使用方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Java配置win10環(huán)境變量過(guò)程圖解

    Java配置win10環(huán)境變量過(guò)程圖解

    這篇文章主要介紹了Java配置win10環(huán)境變量過(guò)程圖解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • SpringBoot實(shí)現(xiàn)AOP切面的三種方式

    SpringBoot實(shí)現(xiàn)AOP切面的三種方式

    Spring,SpringBoot框架憑借多種高效機(jī)制,顯著增強(qiáng)了代碼的功能性,并實(shí)現(xiàn)了切面編程(AOP)的精髓,其核心亮點(diǎn)之一,是運(yùn)用動(dòng)態(tài)代理技術(shù),無(wú)需觸動(dòng)源代碼即可在Bean的運(yùn)行時(shí)為其動(dòng)態(tài)織入額外功能,本文給大家介紹了SpringBoot通過(guò)3種方式實(shí)現(xiàn)AOP切面,需要的朋友可以參考下
    2024-08-08
  • Spring Boot集成Java DSL的實(shí)現(xiàn)代碼

    Spring Boot集成Java DSL的實(shí)現(xiàn)代碼

    這篇文章主要介紹了Spring Boot集成Java DSL的實(shí)現(xiàn)代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-01-01
  • Spring框架接入單機(jī)Redis兩種實(shí)現(xiàn)方式解析

    Spring框架接入單機(jī)Redis兩種實(shí)現(xiàn)方式解析

    這篇文章主要介紹了Spring框架接入單機(jī)Redis兩種實(shí)現(xiàn)方式解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Spring中property-placeholder的使用與解析詳解

    Spring中property-placeholder的使用與解析詳解

    本篇文章主要介紹了Spring中property-placeholder的使用與解析詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • IDEA 錯(cuò)誤 No main class specified的問(wèn)題

    IDEA 錯(cuò)誤 No main class specified的問(wèn)題

    這篇文章主要介紹了IDEA 錯(cuò)誤 No main class specified的問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • 基于java內(nèi)部類作用的深入分析

    基于java內(nèi)部類作用的深入分析

    本篇文章介紹了,基于java內(nèi)部類作用的深入分析。需要的朋友參考下
    2013-05-05
  • java中final修飾符實(shí)例分析

    java中final修飾符實(shí)例分析

    本文通過(guò)實(shí)例向我們展示了java中final修飾符的概念,final修飾的基本變量和引用類型變量的區(qū)別。有需要的小伙伴可以參考下
    2014-11-11
  • Java創(chuàng)建、識(shí)別條形碼和二維碼方法示例

    Java創(chuàng)建、識(shí)別條形碼和二維碼方法示例

    這篇文章主要給大家介紹了關(guān)于Java創(chuàng)建、識(shí)別條形碼和二維碼的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09

最新評(píng)論