ありがとうございます。
ここから 第17段階:共通基盤・運用機能設計(例外処理・ログ・通知・バッチ・AOP整理) に進みます。
ここまでで教材管理システムとして主要機能は揃いました。
現在:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | 教師
└ 教材作成
└ 審査
└ 公開
受講者
└ 受講
└ 進捗管理
管理者
└ ユーザー管理
└ 権限管理
└ 承認管理
共通
└ 監査ログ
└ ファイル管理
|
まで完成しています。
第17段階では、本番運用に耐えられるSpringアプリケーション基盤を設計します。
第17段階 全体構成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | Application
|
+----------------+----------------+
Exception Logging
Handler AOP
Validation Transaction
Notification Batch
|
Database
|
1. パッケージ構成改善
現在の機能別構成をさらに整理します。
推奨:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 | com.example.lms
├ config
│
├ security
│
├ common
│ ├ exception
│ ├ message
│ ├ util
│ └ audit
│
├ domain
│ ├ user
│ ├ content
│ ├ course
│ └ learning
│
├ application
│ ├ service
│ └ usecase
│
├ infrastructure
│ ├ repository
│ ├ mapper
│ └ storage
│
└ web
├ controller
├ form
└ dto
|
2. 例外処理設計
目的
現在:
になる問題を解消します。
3. 例外クラス設計
配置:
BusinessException
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | @Getter
public class BusinessException
extends RuntimeException {
private final String code;
public BusinessException(
String code,
String message){
super(message);
this.code=code;
}
}
|
4. 例外種類
| Exception
├ BusinessException
│
├ ResourceNotFoundException
│
├ UnauthorizedException
│
├ ForbiddenException
│
└ SystemException
|
5. ResourceNotFoundException
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | public class ResourceNotFoundException
extends BusinessException {
public ResourceNotFoundException(
String message){
super(
"NOT_FOUND",
message
);
}
}
|
6. ControllerAdvice
配置:
| common.exception
└ GlobalExceptionHandler
|
GlobalExceptionHandler.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 | @ControllerAdvice
@RequiredArgsConstructor
public class GlobalExceptionHandler {
private final MessageService messageService;
@ExceptionHandler(
ResourceNotFoundException.class
)
public String notFound(
ResourceNotFoundException e,
Model model){
model.addAttribute(
"message",
e.getMessage()
);
return "error/404";
}
@ExceptionHandler(
BusinessException.class
)
public String business(
BusinessException e,
Model model){
model.addAttribute(
"message",
e.getMessage()
);
return "error/error";
}
@ExceptionHandler(Exception.class)
public String system(
Exception e){
return "error/system";
}
}
|
7. エラー画面
構成:
| templates
└ error
├ 404.html
├ error.html
└ system.html
|
404.html
表示:
8. バリデーション共通化
現在:
| @NotBlank
private String title;
|
ですが、メッセージを一元管理します。
9. messages.properties
配置:
| resources
└ messages.properties
|
内容:
| content.title.required=
教材タイトルを入力してください
content.summary.required=
概要を入力してください
file.required=
ファイルを選択してください
|
Form:
| @NotBlank(
message="{content.title.required}"
)
private String title;
|
10. メッセージ管理Service
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | @Service
@RequiredArgsConstructor
public class MessageService {
private final MessageSource source;
public String get(
String code){
return source.getMessage(
code,
null,
Locale.JAPAN
);
}
}
|
11. Spring AOP整理
現在:
があります。
さらに共通化します。
構成:
| common.aop
├ AuditAspect
├ LoggingAspect
└ TransactionAspect
|
12. LoggingAspect
目的:
Service実行時間計測。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 | @Aspect
@Component
@Slf4j
public class LoggingAspect {
@Around(
"execution(* com.example.lms.application..*(..))"
)
public Object log(
ProceedingJoinPoint joinPoint)
throws Throwable {
long start =
System.currentTimeMillis();
try{
return joinPoint.proceed();
}finally{
long time =
System.currentTimeMillis()
-start;
log.info(
"{} {}ms",
joinPoint
.getSignature()
.getName(),
time
);
}
}
}
|
13. トランザクション設計
ルール:
Controller
Service
例:
| @Service
@Transactional
public class ContentService {
}
|
14. Read Only Transaction
検索処理:
| @Transactional(
readOnly=true
)
public List<ContentDto> search(){
}
|
メリット:
15. ログ設計
利用:
Spring Boot標準
構成:
| logs
├ application.log
├ error.log
└ audit.log
|
16. logback-spring.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 | <configuration>
<appender name="FILE"
class="ch.qos.logback.core.FileAppender">
<file>
logs/application.log
</file>
<encoder>
<pattern>
%d %-5level %msg%n
</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="FILE"/>
</root>
</configuration>
|
17. メール通知設計
対象:
構成:
| notification
├ NotificationService
├ MailService
└ Template
|
18. Notificationテーブル
履歴を保持します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | CREATE TABLE notifications (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT,
type VARCHAR(50),
title VARCHAR(200),
message TEXT,
read_flag BOOLEAN,
created_at DATETIME
);
|
19. Notification Entity
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 | @Entity
@Getter
@Setter
public class Notification {
@Id
@GeneratedValue
private Long id;
@ManyToOne
private User user;
private String type;
private String title;
@Column(columnDefinition="TEXT")
private String message;
private Boolean readFlag;
private LocalDateTime createdAt;
}
|
20. 非同期通知
メール送信は時間がかかるため、
| @Async
public void sendMail(){
}
|
を利用します。
設定:
| @EnableAsync
@Configuration
public class AsyncConfig {
}
|
21. バッチ処理設計
Spring Batchを利用します。
用途:
-
古い監査ログ削除
-
期限切れファイル削除
-
受講進捗集計
-
リマインドメール
構成:
| batch
├ AuditCleanupJob
├ ProgressSummaryJob
└ ReminderMailJob
|
22. 定期処理
例:
1
2
3
4
5
6
7
8
9
10
11
12 | @Component
public class ReminderTask {
@Scheduled(
cron="0 0 9 * * MON"
)
public void execute(){
}
}
|
23. 定期処理例
毎週月曜日9時:
| 7日間ログインなし
↓
受講者へ通知
↓
メンターへ通知
|
24. セキュリティログ
追加推奨:
1
2
3
4
5
6
7
8
9
10
11
12
13 | CREATE TABLE security_logs (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT,
event_type VARCHAR(50),
ip_address VARCHAR(50),
created_at DATETIME
);
|
記録:
| LOGIN_SUCCESS
LOGIN_FAILURE
PASSWORD_CHANGE
|
25. 第17段階終了後の構成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 | Spring Boot
Controller
|
Service
|
+---+---+---+
AOP Exception Transaction
|
Repository / Mapper
|
Database
Storage
|
Cloudflare R2
|
第17段階終了時点
追加された機能:
✅ 共通例外処理
✅ エラー画面
✅ Validationメッセージ管理
✅ AOPログ処理
✅ 監査処理整理
✅ トランザクション方針
✅ ログ設計
✅ 通知設計
✅ バッチ設計
✅ セキュリティログ設計
次の 第18段階 では、画面設計とThymeleaf実装方針に進みます。
内容:
-
共通レイアウト設計
-
Bootstrap5設計
-
管理者画面
-
教師画面
-
受講者画面
-
Thymeleaf Fragment設計
-
Form入力画面
-
一覧・詳細・編集画面パターン
-
ページネーション
-
Ajax化する部分
を設計します。