videoEndPoint(VideoRouteHandler videoRouteHandler) {
- return route()
- .nest(path("/videos"), builder -> builder.GET("", videoRouteHandler::listVideos)
- .nest(path("/{name}"), videoBuilder -> videoBuilder.GET("", param("partial"),
- videoRouteHandler::getPartialContent).GET("", videoRouteHandler::getFullContent)
- )
- ).build();
- }
-
- private static RequestPredicate param(String parameter) {
- return RequestPredicates.all().and(request -> request.queryParam(parameter).isPresent());
- }
-}
diff --git a/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/configuration/Bootstrap.java b/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/configuration/Bootstrap.java
deleted file mode 100644
index df6cdb1..0000000
--- a/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/configuration/Bootstrap.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.jmframework.boot.mediastreamingspringbootautoconfigure.configuration;
-
-import com.jmframework.boot.mediastreamingspringbootautoconfigure.model.Video;
-import com.jmframework.boot.mediastreamingspringbootautoconfigure.repository.VideoRepository;
-import com.jmframework.boot.mediastreamingspringbootautoconfigure.services.FileService;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.boot.CommandLineRunner;
-import org.springframework.stereotype.Component;
-
-/**
- * Description: Bootstrap, change description here.
- *
- * @author 钟俊, email: zhongjun@tuguide.cn, date: 10/19/2020 2:51 PM
- **/
-@Slf4j
-@Component
-@RequiredArgsConstructor
-public class Bootstrap implements CommandLineRunner {
- private final VideoRepository videoRepository;
- private final FileService fileService;
-
- @Override
- public void run(String... args) {
- fileService.getAllFiles()
- .doOnNext(path -> log.debug("found file in path: " + path.toUri() + " FileName: " + path.getFileName()))
- .flatMap(path -> {
- Video video = new Video();
- video.setName(path.getFileName().toString());
- video.setLocation(path);
- return videoRepository.addVideo(video);
- })
- .subscribe();
-
- videoRepository.getAllVideos()
- .doOnNext(video -> log.info("Registered video: " + video.getName()))
- .subscribe();
- }
-}
diff --git a/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/configuration/MediaStreamingAutoConfiguration.java b/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/configuration/MediaStreamingAutoConfiguration.java
index 5b07467..d51a222 100644
--- a/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/configuration/MediaStreamingAutoConfiguration.java
+++ b/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/configuration/MediaStreamingAutoConfiguration.java
@@ -1,16 +1,33 @@
package com.jmframework.boot.mediastreamingspringbootautoconfigure.configuration;
+import com.jmframework.boot.mediastreamingspringbootautoconfigure.handler.MediaStreamingExceptionHandler;
+import com.jmframework.boot.mediastreamingspringbootautoconfigure.handler.VideoRouteHandler;
+import com.jmframework.boot.mediastreamingspringbootautoconfigure.repository.VideoRepository;
+import com.jmframework.boot.mediastreamingspringbootautoconfigure.repository.impl.InMemoryVideoOnFileSystemRepository;
+import com.jmframework.boot.mediastreamingspringbootautoconfigure.services.FileService;
+import com.jmframework.boot.mediastreamingspringbootautoconfigure.services.VideoService;
+import com.jmframework.boot.mediastreamingspringbootautoconfigure.services.impl.FileServiceImpl;
+import com.jmframework.boot.mediastreamingspringbootautoconfigure.services.impl.VideoServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.web.reactive.function.server.RequestPredicate;
+import org.springframework.web.reactive.function.server.RequestPredicates;
+import org.springframework.web.reactive.function.server.RouterFunction;
+import org.springframework.web.reactive.function.server.ServerResponse;
import javax.annotation.PostConstruct;
+import static org.springframework.web.reactive.function.server.RequestPredicates.path;
+import static org.springframework.web.reactive.function.server.RouterFunctions.route;
+
/**
* Description: MediaStreamingAutoConfiguration, change description here.
*
- * @author 钟俊, email: zhongjun@tuguide.cn, date: 10/19/2020 2:51 PM
+ * @author Johnny Miller (锺俊), email: johnnysviva@outlook.com, date: 10/19/2020 2:51 PM
**/
@Slf4j
@Configuration
@@ -21,6 +38,73 @@ public class MediaStreamingAutoConfiguration {
@PostConstruct
public void afterInitialization() {
- log.info("afterInitialization: {}", mediaStreamingProperties);
+ log.debug("MediaStreamingAutoConfiguration initialization is done. {}", mediaStreamingProperties);
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public MediaStreamingBootstrap bootstrap(VideoRepository videoRepository, FileService fileService) {
+ return new MediaStreamingBootstrap(videoRepository, fileService, mediaStreamingProperties);
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public WebFluxAutoConfiguration webFluxAutoConfiguration() {
+ return new WebFluxAutoConfiguration();
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public MediaStreamingExceptionHandler mediaStreamingExceptionHandler() {
+ return new MediaStreamingExceptionHandler();
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public VideoRouteHandler videoRouteHandler(VideoService videoService, FileService fileService) {
+ return new VideoRouteHandler(videoService, fileService);
+ }
+
+ /**
+ * Video end point router function.
+ *
+ * TODO: solve Nullable Problems
+ *
+ * @param videoRouteHandler the video route handler
+ * @return the router function
+ */
+ @Bean
+ @SuppressWarnings("NullableProblems")
+ public RouterFunction videoEndPoint(VideoRouteHandler videoRouteHandler) {
+ log.info("videoEndPoint");
+ return route()
+ .nest(path("/videos"), builder -> builder.GET("", videoRouteHandler::listVideos)
+ .nest(path("/{name}"), videoBuilder -> videoBuilder.GET("", param("partial"),
+ videoRouteHandler::getPartialContent).GET("", videoRouteHandler::getFullContent)
+ )
+ ).build();
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public VideoService videoService(VideoRepository videoRepository) {
+ return new VideoServiceImpl(videoRepository);
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public FileService fileService() {
+ return new FileServiceImpl(mediaStreamingProperties);
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public VideoRepository videoRepository() {
+ return new InMemoryVideoOnFileSystemRepository();
+ }
+
+ @SuppressWarnings("SameParameterValue")
+ private static RequestPredicate param(String parameter) {
+ return RequestPredicates.all().and(request -> request.queryParam(parameter).isPresent());
}
}
diff --git a/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/configuration/MediaStreamingBootstrap.java b/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/configuration/MediaStreamingBootstrap.java
new file mode 100644
index 0000000..81f197d
--- /dev/null
+++ b/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/configuration/MediaStreamingBootstrap.java
@@ -0,0 +1,83 @@
+package com.jmframework.boot.mediastreamingspringbootautoconfigure.configuration;
+
+import com.jmframework.boot.mediastreamingspringbootautoconfigure.filewatch.FileWatcher;
+import com.jmframework.boot.mediastreamingspringbootautoconfigure.filewatch.FileWatcherHandler;
+import com.jmframework.boot.mediastreamingspringbootautoconfigure.model.Video;
+import com.jmframework.boot.mediastreamingspringbootautoconfigure.repository.VideoRepository;
+import com.jmframework.boot.mediastreamingspringbootautoconfigure.services.FileService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.CommandLineRunner;
+import reactor.core.publisher.Mono;
+
+import javax.annotation.PostConstruct;
+import java.nio.file.Path;
+
+/**
+ * Description: MediaStreamingBootstrap, change description here.
+ *
+ * @author Johnny Miller (锺俊), email: johnnysviva@outlook.com, date: 10/19/2020 2:51 PM
+ **/
+@Slf4j
+@RequiredArgsConstructor
+public class MediaStreamingBootstrap implements CommandLineRunner {
+ private final VideoRepository videoRepository;
+ private final FileService fileService;
+ private final MediaStreamingProperties mediaStreamingProperties;
+
+ @PostConstruct
+ private void postConstruct() {
+ log.debug("MediaStreamingBootstrap initialization is done. Start to process videos.");
+ log.debug("Starting FileWatcher...");
+ FileWatcher fileWatcher;
+ try {
+ fileWatcher = new FileWatcher(mediaStreamingProperties.getVideoDirectoryOnFileSystem());
+ } catch (Exception e) {
+ log.error("Cannot build FileWatcher, file observation failed! " +
+ "Check `media-streaming.videoDirectoryOnFileSystem` configuration.", e);
+ return;
+ }
+ fileWatcher.setFileWatcherHandler(new FileWatcherHandler() {
+ @Override
+ public void onCreated(Path file) {
+ log.debug("Created file observed: {}", file);
+ Video video = new Video();
+ video.setName(file.getFileName().toString());
+ video.setLocation(file);
+ Mono.just(video).then(videoRepository.addVideo(video)).subscribe();
+ }
+
+ @Override
+ public void onDeleted(Path file) {
+ log.debug("Deleted file observed: {}", file);
+ Mono.just(file).then(videoRepository.deleteVideoByPath(file)).subscribe();
+ }
+
+ @Override
+ public void onModified(Path file) {
+ log.info("Modified file observed: {}", file);
+ Video video = new Video();
+ video.setName(file.getFileName().toString());
+ video.setLocation(file);
+ Mono.just(video).then(videoRepository.addVideo(video)).subscribe();
+ }
+ });
+ }
+
+ @Override
+ public void run(String... args) {
+ fileService.getAllFiles()
+ .doOnNext(path -> log.debug("found file in path: " + path.toUri() + " FileName: " + path.getFileName()))
+ .flatMap(path -> {
+ Video video = new Video();
+ video.setName(path.getFileName().toString());
+ video.setLocation(path);
+ return videoRepository.addVideo(video);
+ })
+ .subscribe();
+
+ videoRepository.getAllVideos()
+ .doOnNext(video -> log.debug("Registered video: " + video.getName()))
+ .subscribe();
+ }
+}
diff --git a/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/configuration/ResourceRegionMessageWriter.java b/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/configuration/ResourceRegionMessageWriter.java
index c5ff414..b1467d4 100644
--- a/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/configuration/ResourceRegionMessageWriter.java
+++ b/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/configuration/ResourceRegionMessageWriter.java
@@ -46,7 +46,7 @@ public class ResourceRegionMessageWriter implements HttpMessageWriter> zeroCopy(Resource resource, ResourceRegion r
return Optional.of(((ZeroCopyHttpOutputMessage) message).writeWith(file, position, count));
} catch (IOException e) {
// Ignored
+ log.error("IO Exception occurred when zeroCopy", e);
}
}
return Optional.empty();
@@ -76,8 +77,9 @@ private static long lengthOf(ResourceRegion resourceRegion) {
if (resourceRegion.getResource().getClass() != InputStreamResource.class) {
try {
return resourceRegion.getResource().contentLength();
- } catch (Exception e) {
+ } catch (IOException e) {
// Ignore Exception
+ log.error("IO Exception occurred when getting length of ResourceRegion.", e);
}
}
return -1;
@@ -184,7 +186,6 @@ public Mono write(Publisher extends ResourceRegion> inputStream,
MediaType resourceMediaType = getResourceMediaType(mediaType, resourceRegion.getResource());
-
headers.setContentType(resourceMediaType);
headers.add(HttpHeaders.CONTENT_RANGE,
"bytes " + startPosition + '-' + endPosition + '/' + contentLength);
diff --git a/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/configuration/WebFluxAutoConfiguration.java b/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/configuration/WebFluxAutoConfiguration.java
index 1d79594..44a9e2d 100644
--- a/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/configuration/WebFluxAutoConfiguration.java
+++ b/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/configuration/WebFluxAutoConfiguration.java
@@ -1,6 +1,5 @@
package com.jmframework.boot.mediastreamingspringbootautoconfigure.configuration;
-import org.springframework.context.annotation.Configuration;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.web.reactive.config.EnableWebFlux;
import org.springframework.web.reactive.config.WebFluxConfigurer;
@@ -11,7 +10,6 @@
* @author Johnny Miller (锺俊), email: johnnysviva@outlook.com
* date 10/19/2020 2:33 PM
**/
-@Configuration
@EnableWebFlux
public class WebFluxAutoConfiguration implements WebFluxConfigurer {
@Override
diff --git a/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/filewatch/FileWatcher.java b/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/filewatch/FileWatcher.java
new file mode 100644
index 0000000..b79c8fa
--- /dev/null
+++ b/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/filewatch/FileWatcher.java
@@ -0,0 +1,97 @@
+package com.jmframework.boot.mediastreamingspringbootautoconfigure.filewatch;
+
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import lombok.Setter;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+
+import javax.annotation.PreDestroy;
+import java.nio.file.*;
+import java.util.Optional;
+import java.util.concurrent.*;
+
+import static java.nio.file.StandardWatchEventKinds.*;
+
+/**
+ * Description: FileWatcher, change description here.
+ *
+ * @author Johnny Miller (锺俊), email: johnnysviva@outlook.com, date: 10/20/2020 3:19 PM
+ * @see Inspired by file-watcher
+ **/
+@Slf4j
+@Setter
+public class FileWatcher {
+ private static final ThreadFactory NAMED_THREAD_FACTORY =
+ new ThreadFactoryBuilder().setNameFormat("file-watcher-thread-%d").build();
+ private static final ExecutorService THREAD_POOL =
+ new ThreadPoolExecutor(1, 2, 0L, TimeUnit.MILLISECONDS,
+ new LinkedBlockingQueue<>(1024), NAMED_THREAD_FACTORY, new ThreadPoolExecutor.AbortPolicy());
+
+ private final Path monitoredPath;
+ private FileWatcherHandler fileWatcherHandler;
+
+ public FileWatcher(String directory) {
+ this(Paths.get(directory));
+ }
+
+ @SneakyThrows
+ private FileWatcher(Path path) {
+ this.monitoredPath = path;
+ this.monitoredPath.register(WatchServiceSingleton.getInstance(),
+ StandardWatchEventKinds.ENTRY_CREATE,
+ StandardWatchEventKinds.ENTRY_DELETE,
+ StandardWatchEventKinds.ENTRY_MODIFY);
+ THREAD_POOL.execute(this::monitor);
+ }
+
+ private void monitor() {
+ log.debug("Started watching: {}", this.monitoredPath);
+ while (true) {
+ // wait for key to be signaled
+ Optional optionalWatchKey = Optional.ofNullable(WatchServiceSingleton.getInstance().poll());
+ if (optionalWatchKey.isPresent()) {
+ var watchKey = optionalWatchKey.get();
+ for (var watchEvent : watchKey.pollEvents()) {
+ WatchEvent.Kind> kind = watchEvent.kind();
+
+ // This key is registered only for ENTRY_CREATE events,
+ // but an OVERFLOW event can occur regardless if events are lost or discarded.
+ if (kind == OVERFLOW) {
+ continue;
+ }
+
+ // The filename is the context of the event.
+ @SuppressWarnings("unchecked")
+ WatchEvent event = (WatchEvent) watchEvent;
+ Path filename = event.context();
+
+ // Resolve the filename against the directory.
+ // If the filename is "test" and the directory is "foo", the resolved name is "foo/test".
+ Path child = monitoredPath.resolve(filename);
+ if (kind == ENTRY_CREATE) {
+ fileWatcherHandler.onCreated(child);
+ } else if (kind == ENTRY_DELETE) {
+ fileWatcherHandler.onDeleted(child);
+ } else if (kind == ENTRY_MODIFY) {
+ fileWatcherHandler.onModified(child);
+ }
+ }
+
+ // Reset the key -- this step is critical if you want to receive further watch events.
+ // If the key is no longer valid, the directory is inaccessible so exit the loop.
+ boolean valid = watchKey.reset();
+ if (!valid) {
+ log.debug("The watch key wasn't valid. {}", watchKey);
+ return;
+ }
+ }
+ }
+ }
+
+ @PreDestroy
+ @SneakyThrows
+ private void onPreDestroy() {
+ THREAD_POOL.awaitTermination(5, TimeUnit.SECONDS);
+ log.debug("THREAD_POOL for FileWatcher was terminated.");
+ }
+}
diff --git a/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/filewatch/FileWatcherHandler.java b/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/filewatch/FileWatcherHandler.java
new file mode 100644
index 0000000..8a9bb91
--- /dev/null
+++ b/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/filewatch/FileWatcherHandler.java
@@ -0,0 +1,31 @@
+package com.jmframework.boot.mediastreamingspringbootautoconfigure.filewatch;
+
+import java.nio.file.Path;
+
+/**
+ * Description: FileWatcherHandler, change description here.
+ *
+ * @author Johnny Miller (锺俊), email: johnnysviva@outlook.com, date: 10/20/2020 3:22 PM
+ */
+public interface FileWatcherHandler {
+ /**
+ * On created.
+ *
+ * @param file the file
+ */
+ void onCreated(Path file);
+
+ /**
+ * On deleted.
+ *
+ * @param file the file
+ */
+ void onDeleted(Path file);
+
+ /**
+ * On modified.
+ *
+ * @param file the file
+ */
+ void onModified(Path file);
+}
diff --git a/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/filewatch/WatchServiceSingleton.java b/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/filewatch/WatchServiceSingleton.java
new file mode 100644
index 0000000..f3cf74b
--- /dev/null
+++ b/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/filewatch/WatchServiceSingleton.java
@@ -0,0 +1,30 @@
+package com.jmframework.boot.mediastreamingspringbootautoconfigure.filewatch;
+
+import lombok.SneakyThrows;
+
+import java.nio.file.FileSystems;
+import java.nio.file.WatchService;
+
+/**
+ * Description: WatchServiceSingleton, change description here.
+ *
+ * @author Johnny Miller (锺俊), email: johnnysviva@outlook.com, date: 10/20/2020 4:52 PM
+ **/
+public class WatchServiceSingleton {
+ private static volatile WatchService singletonInstance;
+
+ private WatchServiceSingleton() {
+ }
+
+ @SneakyThrows
+ public static WatchService getInstance() {
+ if (singletonInstance == null) {
+ synchronized (WatchServiceSingleton.class) {
+ if (singletonInstance == null) {
+ singletonInstance = FileSystems.getDefault().newWatchService();
+ }
+ }
+ }
+ return singletonInstance;
+ }
+}
diff --git a/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/handler/MediaStreamingExceptionHandler.java b/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/handler/MediaStreamingExceptionHandler.java
index 75af71d..e8983a6 100644
--- a/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/handler/MediaStreamingExceptionHandler.java
+++ b/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/handler/MediaStreamingExceptionHandler.java
@@ -10,7 +10,6 @@
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
-import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.handler.WebFluxResponseStatusExceptionHandler;
import org.springframework.web.server.ServerWebExchange;
@@ -28,12 +27,11 @@
**/
@Slf4j
@Order(-2)
-@Component
public class MediaStreamingExceptionHandler extends WebFluxResponseStatusExceptionHandler {
final SimpleDateFormat simpleDate = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
public MediaStreamingExceptionHandler() {
- log.info("Initialized MediaStreamingExceptionHandler");
+ log.debug("Initialized MediaStreamingExceptionHandler");
}
@Override
diff --git a/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/handler/VideoRouteHandler.java b/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/handler/VideoRouteHandler.java
index fccd406..f1a0043 100644
--- a/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/handler/VideoRouteHandler.java
+++ b/media-streaming-spring-boot-autoconfigure/src/main/java/com/jmframework/boot/mediastreamingspringbootautoconfigure/handler/VideoRouteHandler.java
@@ -4,13 +4,12 @@
import com.jmframework.boot.mediastreamingspringbootautoconfigure.services.FileService;
import com.jmframework.boot.mediastreamingspringbootautoconfigure.services.VideoService;
import lombok.Data;
-import org.springframework.beans.factory.annotation.Autowired;
+import lombok.RequiredArgsConstructor;
import org.springframework.core.io.UrlResource;
import org.springframework.core.io.support.ResourceRegion;
import org.springframework.http.CacheControl;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
-import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.Exceptions;
@@ -22,24 +21,18 @@
*
* @author Johnny Miller (锺俊), email: johnnysviva@outlook.com, date: 10/19/2020 5:29 PM
*/
-@Component
+@RequiredArgsConstructor
public class VideoRouteHandler {
private final VideoService videoService;
private final FileService fileService;
- @Autowired
- public VideoRouteHandler(VideoService videoService, FileService fileService) {
- this.videoService = videoService;
- this.fileService = fileService;
- }
-
-
/**
* List videos mono.
*
* @param request the request
* @return the mono
*/
+
public Mono listVideos(ServerRequest request) {
Flux