Spring Boot自定义Starter之FastDFS自动配置

https://github.com/poai/spring-starter-fastdfs.git

最近Spring Boot用的较多,使用过程中发现一些问题

  1. Spring data 下的子项目 redis、elasticsearch、rabbitmq等都提供了深度封装的API
  2. 由于习惯了原生API的简洁性因此大部分场景下并不倾向于去使用这些模块封装的API
  3. 对于Reids\Elasticsearch等开源组件来说使用频率却是比较高的,因此进行模块化配置是必要的。

基于以上因此,计划基于Spring Boot提供的Auto-configuration 机制自定义一些适合自己团队的编程模式。本节对FastDFS于Spring Boot进行集成,做到自动配置,开放源码供学习。

原理

        当时读的2.1.3.RELEASE版本的文档 https://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/reference/htmlsingle/ 参考章节49.1,49.2,49.3章节。

        Spring Boot 提供了自动配置机制,以“@EnableAutoConfiguration” 注解为入口,简单说 Spring Boot在启动时会去从类路径下"META-INF/spring.factories"文件中查找所有以"spring.boot.enableautoconfiguration"为属性的配置类作为初始的配置文件进行加载[49.2节]。EnableAutoConfiguration 注解定义如下:

Spring Boot自定义Starter之FastDFS自动配置_第1张图片

        Spring Boot提供了"Condition"系列注解用于对导入的配置进行判定,只有满足特定条件时一个Bean才能被加载到IOC容器中[49.3节]。

        基于此我们可以借助于“Auto-configuration”机制及“Auto-configuration”特性自动继承FastDFS。

实现

相关依赖:


	org.springframework.boot
	spring-boot-autoconfigure
	${spring-boot-version}


	org.springframework.boot
	spring-boot-configuration-processor
	${spring-boot-version}


	org.csource
	fastdfs-client-java
	${fastdfs-version}



	commons-io
	commons-io
	2.5

组件版本定义如下:


	1.8
	2.1.0.RELEASE
	1.27-RELEASE

创建配置类,团队内部做以下约定:

  • FastDFS的配置必须使用client.conf作为文件名且必须放在Spring Boot项目类路径下的config目录下。
  • 依赖于FastDFS的项目必须配置fdfs.enabled=true才生效。
/**
 * 满足以下条件加载FastDFS模块:
* 1.类路径中存在StorageClient.class及StorageServer.class
* 2.fdfs.enabled=true **/ @Configuration @ConditionalOnClass(value = { StorageClient.class, StorageServer.class }) @ConditionalOnProperty(name = "fdfs.enabled", havingValue = "true") public class FDFSAutoConfiguration { private static final Log log = LogFactory.getLog(EnableFDFS.class); static { try { File file = ResourceUtils.getFile("classpath:config/client.conf"); ClientGlobal.init(file.getAbsolutePath()); log.info("FastDFS init success."); } catch (FileNotFoundException e) { e.printStackTrace(); log.error(e); } catch (IOException e) { e.printStackTrace(); log.error(e); } catch (MyException e) { e.printStackTrace(); log.error(e); } } @Bean public FDFSUtil FDFSUtil() { return new FDFSUtil(); } private boolean enabled; public boolean isEnabled() { return enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } }

参考其他项目提供EnableFDFS用来显示的引入FastDFS模块,定义注解EnableFDFS

@Import(value = FDFSAutoConfiguration.class)
@Target(value = { ElementType.TYPE })
@Retention(value = RetentionPolicy.RUNTIME)
public @interface EnableFDFS {
}

定义FastDFS工具类开放给业务系统。这里定义为FDFSUtil,暂时提供了三个方法,同时对StorageClient进行了线程本地化处理。

public class FDFSUtil {
	private static Log log = LogFactory.getLog(FDFSUtil.class);
	private static ThreadLocal threadLocal = new ThreadLocal<>();

	public String[] upload(byte[] image) {
		try {
			long start = System.currentTimeMillis();
			String values[] = getClient().upload_file(image, ".jpg", null);
			long end = System.currentTimeMillis();
			log.debug("UPLOAD FILE SUCCESS USE TIME:" + (end - start) + ",RESULT:" + Arrays.asList(values));
			return values;
		} catch (Exception e) {
			log.error(e);
			return null;
		}
	}

	public byte[] download(String group, String path) {
		try {
			long start = System.currentTimeMillis();
			byte[] image = getClient().download_file(group, path);
			long end = System.currentTimeMillis();
			log.debug("DOWNLOAD FILE SUCCESS USE TIME:" + (end - start));
			return image;
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e);
		}
		return null;
	}

	public StorageClient getClient() {
		if (threadLocal.get() == null) {
			synchronized (threadLocal) {
				if (threadLocal.get() == null) {
					threadLocal.set(new StorageClient(null, null));
				}
			}
		}
		return threadLocal.get();
	}
}

在META-INF目录下创建spring.factories文件,及定义配置文件的additional-spring-configuration-metadata.json元数据文件

spring.factories中做如下配置

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.zjf.fastdfs.FDFSAutoConfiguration

 

使用

    有两种使用模式,默认情况下直接依赖“spring-starter-fastdfs”项目并配置fdfs.enabled=true则会自动初始化FastDFS,可直接从容器中获取FDFSUtil对象。另外可以显示的使用@EnableFDFS注解来显示 的引用(实际上默认已经引用除非发布时没有提供spring.factories中的配置)。注意配置文件一定要放对位置。

@SpringBootApplication
@EnableFDFS
public class WebServiceApplication {
	private static Log log = LogFactory.getLog(WebServiceApplication.class);
	@Autowired
	private FDFSUtil FDFSUtil;

	public static void main(String[] args) throws SchedulerException {
                SpringApplication.run(WebServiceApplication.class, args);

	}

}

源码

https://github.com/poai/spring-starter-fastdfs.git

 

 

 

 

 

你可能感兴趣的:(Spring,Boot)