亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Spring注解驅(qū)動(dòng)之BeanPostProcessor后置處理器講解

 更新時(shí)間:2022年09月30日 10:01:00   作者:融極  
這篇文章主要介紹了Spring注解驅(qū)動(dòng)之BeanPostProcessor后置處理器講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

概述

在學(xué)習(xí)Spring的時(shí)候,在了解基本用法的時(shí)候,如果有時(shí)間一定要深入源碼了解Spring的底層原理,這樣在做一些適配工作、寫(xiě)一些輪子的時(shí)候就會(huì)比較容易,否則會(huì)很難,甚至一頭霧水,無(wú)法完成工作。

吃透Spring的原理和源碼,往往可以拉開(kāi)人們之間的差距,當(dāng)前只要是使用Java技術(shù)棧開(kāi)發(fā)的Web項(xiàng)目,幾乎都會(huì)使用Spring框架。

而且目前各招聘網(wǎng)站上對(duì)于Java開(kāi)發(fā)的要求幾乎清一色的都是熟悉或者精通Spring,所以,你很有必要學(xué)習(xí)Spring的細(xì)節(jié)知識(shí)點(diǎn)。

BeanPostProcessor后置處理器概述

首先,看下BeanPostProcessor的源碼。

package org.springframework.beans.factory.config;

import org.springframework.beans.BeansException;

public interface BeanPostProcessor {
	Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;

	Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

從源碼可以看出,BeanPostProcessor是一個(gè)接口,其中有兩個(gè)方法:

postProcessBeforeInitialization和postProcessAfterInitialization這兩個(gè)方法分別是在Spring容器中的bean初始化前后執(zhí)行,所以Spring容器中的每個(gè)bean對(duì)象初始化前后,都會(huì)執(zhí)行BeanPostProcessor接口的兩個(gè)方法。

也就是說(shuō),postProcessBeforeInitialization方法會(huì)在bean實(shí)例化和屬性設(shè)置之后,自定義初始化方法之前被調(diào)用,而postProcessAfterInitialization方法會(huì)在自定義初始化方法之后被調(diào)用。當(dāng)容器中存在多個(gè)BeanPostProcessor的實(shí)現(xiàn)類(lèi)時(shí),會(huì)按照它們?cè)谌萜髦凶?cè)的順序執(zhí)行。對(duì)于自定義的BeanPostProcessor實(shí)現(xiàn)類(lèi),還可以讓其實(shí)現(xiàn)Ordered接口自定義排序。

因此我們可以在每個(gè)bean對(duì)象初始化前后,加上自己的邏輯。實(shí)現(xiàn)方式是自定義一個(gè)BeanPostProcessor接口的實(shí)現(xiàn)類(lèi),例如MyBeanPostProcessor,然后在該類(lèi)的postProcessBeforeInitialization和postProcessAfterInitialization這兩個(gè)方法寫(xiě)上自定義邏輯。

BeanPostProcessor后置處理器實(shí)例

我們創(chuàng)建一個(gè)MyBeanPostProcessor類(lèi),實(shí)現(xiàn)BeanPostProcessor接口,如下所示。

package com.meimeixia.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

@Component // 將后置處理器加入到容器中,這樣的話,Spring就能讓它工作了,否則無(wú)法工作
public class MyBeanPostProcessor implements BeanPostProcessor {

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("postProcessBeforeInitialization..." + beanName + "=>" + bean);
		return bean;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("postProcessAfterInitialization..." + beanName + "=>" + bean);
		return bean;
	}
}

接下來(lái),我們應(yīng)該是要編寫(xiě)測(cè)試用例來(lái)進(jìn)行測(cè)試了。

package com.meimeixia.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

import com.meimeixia.bean.Car;

@ComponentScan("com.meimeixia.bean")
@Configuration
public class MainConfigOfLifeCycle {

	@Bean(initMethod="init", destroyMethod="destroy")
	public Car car() {
		return new Car();
	}	
}

第二處改動(dòng)是將Cat類(lèi)上添加的@Scope(“prototype”)注解給注釋掉,因?yàn)樵蹅冎白鰷y(cè)試的時(shí)候,也是將Cat對(duì)象設(shè)置成多實(shí)例bean了。

package com.meimeixia.bean;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

// @Scope("prototype")
@Component
public class Cat implements InitializingBean, DisposableBean {
	
	public Cat() {
		System.out.println("cat constructor...");
	}

	/**
	 * 會(huì)在容器關(guān)閉的時(shí)候進(jìn)行調(diào)用
	 */
	@Override
	public void destroy() throws Exception {
		// TODO Auto-generated method stub
		System.out.println("cat destroy...");
	}

	/**
	 * 會(huì)在bean創(chuàng)建完成,并且屬性都賦好值以后進(jìn)行調(diào)用
	 */
	@Override
	public void afterPropertiesSet() throws Exception {
		// TODO Auto-generated method stub
		System.out.println("cat afterPropertiesSet...");
	}
}

好了,現(xiàn)在咱們就可以編寫(xiě)測(cè)試用例來(lái)進(jìn)行測(cè)試了。

可喜的是,我們也不用再編寫(xiě)一個(gè)測(cè)試用例了,直接運(yùn)行IOCTest_LifeCycle類(lèi)中的test01()方法就行,該方法的代碼如下所示。

@Test
public void test01() {
    // 1. 創(chuàng)建IOC容器
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
    System.out.println("容器創(chuàng)建完成");
    // 關(guān)閉容器
    applicationContext.close();
}

此時(shí),運(yùn)行IOCTest_LifeCycle類(lèi)中的test01()方法,輸出的結(jié)果信息如下所示。

可以看到,postProcessBeforeInitialization方法會(huì)在bean實(shí)例化和屬性設(shè)置之后,自定義初始化方法之前被調(diào)用,而postProcessAfterInitialization方法會(huì)在自定義初始化方法之后被調(diào)用。

當(dāng)然了,也可以讓我們自己寫(xiě)的MyBeanPostProcessor類(lèi)來(lái)實(shí)現(xiàn)Ordered接口自定義排序,如下所示。

package com.meimeixia.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

/**
 * 后置處理器,在初始化前后進(jìn)行處理工作
 * @author liayun
 *
 */
@Component // 將后置處理器加入到容器中,這樣的話,Spring就能讓它工作了
public class MyBeanPostProcessor implements BeanPostProcessor, Ordered {
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("postProcessBeforeInitialization..." + beanName + "=>" + bean);
		return bean;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("postProcessAfterInitialization..." + beanName + "=>" + bean);
		return bean;
	}

	@Override
	public int getOrder() {
		return 3;
	}
}

BeanPostProcessor后置處理器作用

后置處理器可用于bean對(duì)象初始化前后進(jìn)行邏輯增強(qiáng)。

Spring提供了BeanPostProcessor接口的很多實(shí)現(xiàn)類(lèi),例如AutowiredAnnotationBeanPostProcessor用于@Autowired注解的實(shí)現(xiàn),AnnotationAwareAspectJAutoProxyCreator用于Spring AOP的動(dòng)態(tài)代理等等。

除此之外,我們還可以自定義BeanPostProcessor接口的實(shí)現(xiàn)類(lèi),在其中寫(xiě)入咱們需要的邏輯。

bean的初始化和銷(xiāo)毀流程

我們知道BeanPostProcessor的postProcessBeforeInitialization()方法是在bean的初始化之前被調(diào)用;而postProcessAfterInitialization()方法是在bean初始化的之后被調(diào)用。

并且bean的初始化和銷(xiāo)毀方法我們可以通過(guò)如下方式進(jìn)行指定。

1. 通過(guò)@Bean指定init-method和destroy-method

@Bean(initMethod="init", destroyMethod="destroy")

2. 通過(guò)讓bean實(shí)現(xiàn)InitializingBean和DisposableBean這倆接口

@Componentpublic class Cat implements InitializingBean, DisposableBean {}

3. 使用JSR-250規(guī)范里面定義的@PostConstruct和@PreDestroy這倆注解

  • @PostConstruct:在bean創(chuàng)建完成并且屬性賦值完成之后,來(lái)執(zhí)行初始化方法
  • @PreDestroy:在容器銷(xiāo)毀bean之前通知我們進(jìn)行清理工作

4. 通過(guò)讓bean實(shí)現(xiàn)BeanPostProcessor接口

@Component // 將后置處理器加入到容器中,這樣的話,Spring就能讓它工作了
public class MyBeanPostProcessor implements BeanPostProcessor, Ordered {}

通過(guò)以上四種方式就可以對(duì)bean的整個(gè)生命周期進(jìn)行控制:

  • bean的實(shí)例化:調(diào)用bean的構(gòu)造方法,我們可以在bean的無(wú)參構(gòu)造方法中執(zhí)行相應(yīng)的邏輯。
  • bean的初始化:在初始化時(shí)可以通過(guò)BeanPostProcessor的postProcessBeforeInitialization()方法和postProcessAfterInitialization()方法進(jìn)行攔截,執(zhí)行自定義的邏輯。通過(guò)@PostConstruct注解、InitializingBean和init-method來(lái)指定bean初始化前后執(zhí)行的方法,在該方法中可以執(zhí)行自定義的邏輯。
  • bean的銷(xiāo)毀:可以通過(guò)@PreDestroy注解、DisposableBean和destroy-method來(lái)指定bean在銷(xiāo)毀前執(zhí)行的方法,在方法中可以執(zhí)行自定義的邏輯。

所以,通過(guò)上述4種方式,我們可以控制Spring中bean的整個(gè)生命周期。

BeanPostProcessor源碼解析

如果想深刻理解BeanPostProcessor的工作原理,那么就不得不看下相關(guān)的源碼,我們可以在MyBeanPostProcessor類(lèi)的postProcessBeforeInitialization()方法和postProcessAfterInitialization()方法這兩處打上斷點(diǎn)來(lái)進(jìn)行調(diào)試,如下所示。 

public class MyBeanPostProcessor implements BeanPostProcessor, Ordered {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization" + ",beanName:"+beanName + ",bean=>" + bean);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization" + ",beanName:"+beanName + ",bean=>" + bean);
        return bean;
    }

    @Override
    public int getOrder() {
        return 3;
    }
}

通過(guò)斷點(diǎn)調(diào)試,我們可以看到,在applyBeanPostProcessorBeforeInitialization()方法中,會(huì)遍歷所有BeanPostProcessor對(duì)象,然后依次執(zhí)行所有BeanPostProcessor對(duì)象的postProcessorBeforeInitialization()方法,一旦BeanPostProcessor對(duì)象的postProcessBeforeInitialization()方法返回null以后,則后面的BeanPostProcessor對(duì)象便不再執(zhí)行了,而是直接退出for循環(huán)。這些都是我們看源碼看到的。

看Spring源碼,我們還看到一個(gè)細(xì)節(jié),在Spring中調(diào)用initializeBean()方法之前,還調(diào)用了populateBean()方法來(lái)為bean的屬性賦值。

經(jīng)過(guò)一系列的跟蹤源碼分析,我們可以將關(guān)鍵代碼的調(diào)用過(guò)程使用如下偽代碼表述出來(lái)。

populateBean(beanName, mbd, instanceWrapper); // 給bean進(jìn)行屬性賦值
initializeBean(beanName, exposedObject, mbd)
{
	applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
	invokeInitMethods(beanName, wrappedBean, mbd); // 執(zhí)行自定義初始化
	applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

也就是說(shuō),在Spring中,調(diào)用initializeBean()方法之前,調(diào)用了populateBean()方法為bean的屬性賦值,為bean的屬性賦好值之后,再調(diào)用initializeBean()方法進(jìn)行初始化。

在initializeBean()中,調(diào)用自定義的初始化方法(即invokeInitMethods())之前,調(diào)用了applyBeanPostProcessorsBeforeInitialization()方法,而在調(diào)用自定義的初始化方法之后,又調(diào)用了applyBeanPostProcessorsAfterInitialization()方法。至此,整個(gè)bean的初始化過(guò)程就這樣結(jié)束了。

BeanPostProcessor接口在Spring底層的應(yīng)用案例

ApplicationContextAwareProcessor類(lèi)

org.springframework.context.support.ApplicationContextAwareProcessor是BeanPostProcessor接口的一個(gè)實(shí)現(xiàn)類(lèi),這個(gè)類(lèi)的作用是可以向組件中注入IOC容器,大致的源碼如下。

注意:我這里的Spring版本為4.3.12.RELEASE。

那具體如何使用ApplicationContextAwareProcessor類(lèi)向組件中注入IOC容器呢?

如果需要向組件中注入IOC容器,那么可以讓組件實(shí)現(xiàn)ApplicationContextAware接口。

例如,我們創(chuàng)建一個(gè)創(chuàng)建一個(gè)Dog類(lèi),使其實(shí)現(xiàn)ApplicationContextAware接口,此時(shí),我們需要實(shí)現(xiàn)ApplicationContextAware接口中的setApplicationContext()方法,在setApplicationContext()方法中有一個(gè)ApplicationContext類(lèi)型的參數(shù),這個(gè)就是IOC容器對(duì)象,我們可以在Dog類(lèi)中定義一個(gè)ApplicationContext類(lèi)型的成員變量,然后在setApplicationContext()方法中為這個(gè)成員變量賦值,此時(shí)就可以在Dog類(lèi)中的

其他方法中使用ApplicationContext對(duì)象了,如下所示。

package com.meimeixia.bean;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * ApplicationContextAwareProcessor這個(gè)類(lèi)的作用是可以幫我們?cè)诮M件里面注入IOC容器,
 * 怎么注入呢?我們想要IOC容器的話,比如我們這個(gè)Dog組件,只需要實(shí)現(xiàn)ApplicationContextAware接口就行
 * 
 */
@Component
public class Dog implements ApplicationContextAware {
	
	private ApplicationContext applicationContext;

	public Dog() {
		System.out.println("dog constructor...");
	}
	
	// 在對(duì)象創(chuàng)建完成并且屬性賦值完成之后調(diào)用
	@PostConstruct
	public void init() { 
		System.out.println("dog...@PostConstruct...");
	}
	
	// 在容器銷(xiāo)毀(移除)對(duì)象之前調(diào)用
	@PreDestroy
	public void destory() {
		System.out.println("dog...@PreDestroy...");
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { // 在這兒打個(gè)斷點(diǎn)調(diào)試一下
		// TODO Auto-generated method stub
		this.applicationContext = applicationContext;
	}	
}

看到這里,相信不少小伙伴們都有一種很熟悉的感覺(jué),沒(méi)錯(cuò),我之前也在項(xiàng)目中使用過(guò)!是的,這就是BeanPostProcessor在Spring底層的一種使用場(chǎng)景。至于上面的案例代碼為何會(huì)在setApplicationContext()方法中獲取到ApplicationContext對(duì)象,這就是ApplicationContextAwareProcessor類(lèi)的功勞了!

接下來(lái),我們就深入分析下ApplicationContextAwareProcessor類(lèi)。

我們先來(lái)看下ApplicationContextAwareProcessor類(lèi)中對(duì)于postProcessBeforeInitialization()方法的實(shí)現(xiàn),如下所示。

在bean初始化之前,首先對(duì)當(dāng)前bean的類(lèi)型進(jìn)行判斷,如果當(dāng)前bean的類(lèi)型不是EnvironmentAware,不是EmbeddedValueResolverAware,不是ResourceLoaderAware,不是ApplicationEventPublisherAware,不是MessageSourceAware,也不是ApplicationContextAware,那么直接返回bean。

如果是上面類(lèi)型中的一種類(lèi)型,那么最終會(huì)調(diào)用invokeAwareInterfaces()方法,并將bean傳遞給該方法。

invokeAwareInterfaces()方法又是個(gè)什么呢?我們繼續(xù)看invokeAwareInterfaces()方法的源碼,如下所示。

可以看到invokeAwareInterfaces()方法的源碼比較簡(jiǎn)單,就是判斷當(dāng)前bean屬于哪種接口類(lèi)型,然后將bean強(qiáng)轉(zhuǎn)為哪種接口類(lèi)型的對(duì)象,接著調(diào)用接口中的方法,將相應(yīng)的參數(shù)傳遞到接口的方法中。

我們可以看到,此時(shí)會(huì)將this.applicationContext傳遞到ApplicationContextAware接口的setApplicationContext()方法中。所以,我們?cè)贒og類(lèi)的setApplicationContext()方法中就可以直接接收到ApplicationContext對(duì)象了。

BeanValidationPostProcessor類(lèi)

org.springframework.validation.beanvalidation.BeanValidationPostProcessor類(lèi)注意是用來(lái)為bean進(jìn)行校驗(yàn)操作的,當(dāng)我們創(chuàng)建bean,并為bean賦值后,我們可以通過(guò)BeanValidationPostProcessor類(lèi)為bean進(jìn)行校驗(yàn)操作。BeanValidationPostProcessor類(lèi)源碼如下:

這里,我們也來(lái)看看postProcessBeforeInitialization()方法和postProcessAfterInitialization()方法的實(shí)現(xiàn),如下所示。

InitDestroyAnnotationBeanPostProcessor類(lèi)

org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor類(lèi)主要用來(lái)處理@PostConstruct注解和@PreDestroy注解。

使用了@PostConstruct注解和@PreDestroy注解來(lái)標(biāo)注方法,Spring怎么就知道什么時(shí)候執(zhí)行@PostConstruct注解標(biāo)注的方法,什么時(shí)候執(zhí)行@PreDestroy注解標(biāo)注的方法呢?這就要?dú)w功于InitDestroyAnnotationBeanPostProcessor類(lèi)了。

接下來(lái),我們也通過(guò)Debug的方式來(lái)跟進(jìn)下代碼的執(zhí)行流程。首先,在Dog類(lèi)的initt()方法上打上一個(gè)斷點(diǎn),如下所示。

在InitDestroyAnnotationBeanPostProcessor類(lèi)的postProcessBeforeInitialization()方法中,首先會(huì)找到bean中有關(guān)生命周期的注解,比如@PostConstruct注解等,找到這些注解之后,則將這些信息賦值給LifecycleMetadata類(lèi)型的變量metadata,之后調(diào)用metadata的invokeInitMethods()方法,通過(guò)反射來(lái)調(diào)用標(biāo)注了@PostConstruct注解的方法。

這就是為什么標(biāo)注了@PostConstruct注解的方法會(huì)被Spring執(zhí)行的原因。

	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
		try {
			metadata.invokeInitMethods(bean, beanName);
		}
		catch (InvocationTargetException ex) {
			throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
		}
		catch (Throwable ex) {
			throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
		}
		return bean;
	}

AutowiredAnnotationBeanPostProcessor類(lèi)

org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor類(lèi)主要是用于處理標(biāo)注了@Autowired注解的變量或方法。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Spring Bean生命周期源碼原理圖解

    Spring Bean生命周期源碼原理圖解

    這篇文章主要介紹了Spring Bean生命周期源碼原理圖解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Springboot 掃描mapper接口的2種操作

    Springboot 掃描mapper接口的2種操作

    這篇文章主要介紹了Springboot 掃描mapper接口的2種操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-01-01
  • 輕松掌握J(rèn)ava享元模式

    輕松掌握J(rèn)ava享元模式

    這篇文章主要幫助大家輕松掌握J(rèn)ava享元模式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • IntelliJ IDEA打開(kāi)多個(gè)Maven的module且相互調(diào)用代碼的方法

    IntelliJ IDEA打開(kāi)多個(gè)Maven的module且相互調(diào)用代碼的方法

    這篇文章主要介紹了IntelliJ IDEA打開(kāi)多個(gè)Maven的module且相互調(diào)用代碼的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-02-02
  • Java的垃圾強(qiáng)制回收實(shí)例分析

    Java的垃圾強(qiáng)制回收實(shí)例分析

    這篇文章主要介紹了Java的垃圾強(qiáng)制回收,結(jié)合實(shí)例形式分析了java垃圾強(qiáng)制回收的相關(guān)原理及實(shí)現(xiàn)方法,需要的朋友可以參考下
    2019-08-08
  • Java工程使用ffmpeg進(jìn)行音視頻格式轉(zhuǎn)換的實(shí)現(xiàn)

    Java工程使用ffmpeg進(jìn)行音視頻格式轉(zhuǎn)換的實(shí)現(xiàn)

    FFmpeg是一套可以用來(lái)記錄、轉(zhuǎn)換數(shù)字音頻、視頻,并能將其轉(zhuǎn)化為流的開(kāi)源計(jì)算機(jī)程序,本文主要介紹了Java工程使用ffmpeg進(jìn)行音視頻格式轉(zhuǎn)換的實(shí)現(xiàn)
    2024-02-02
  • Mybatis省略@Param注解原理分析

    Mybatis省略@Param注解原理分析

    這篇文章主要介紹了Mybatis省略@Param注解原理分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Storm框架整合springboot的方法

    Storm框架整合springboot的方法

    Storm框架中的每個(gè)Spout和Bolt都相當(dāng)于獨(dú)立的應(yīng)用,Strom在啟動(dòng)spout和bolt時(shí)提供了一個(gè)open方法(spout)和prepare方法(bolt)。這篇文章主要介紹了Storm框架整合springboot的方法,需要的朋友可以參考下
    2018-11-11
  • intelliJ IDEA 多行選中相同內(nèi)容的快捷鍵分享

    intelliJ IDEA 多行選中相同內(nèi)容的快捷鍵分享

    這篇文章主要介紹了intelliJ IDEA 多行選中相同內(nèi)容的快捷鍵分享,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02
  • Java使用poi操作excel實(shí)例解析

    Java使用poi操作excel實(shí)例解析

    這篇文章主要為大家詳細(xì)介紹了Java使用poi操作excel的簡(jiǎn)單實(shí)例,感興趣的小伙伴們可以參考一下
    2016-05-05

最新評(píng)論