https://github.com/poai/spring-starter-fastdfs.git
最近Spring Boot用的较多,使用过程中发现一些问题
基于以上因此,计划基于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提供了"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模块:
* 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