1. AOP とは何ですか?
AOP (Aspect-Oriented Programming: アスペクト指向プログラミング)、AOP について言えば、Spring フレームワークを学習したことのあるほとんどの人は、それが Spring の 3 つの中心的なアイデア (IOC: Inversion of Control) の 1 つであることを知っています。 、DI: 依存性注入、AOP: アスペクト指向プログラミング)。ビジネスには関係しないが、一般的にビジネス モジュールによって呼び出されるロジックや責任 (トランザクション処理、ログ管理、権限制御など) をカプセル化して、システム内のコードの重複を減らし、負荷を減らすことができます。モジュール間の結合が容易になり、将来の拡張性と保守性にも役立ちます。
2.AOP は何をしましたか?
簡単に言うと、AOP は主に 3 つのことを行います:
#1. どこに介入するか、つまり、ビジネス以外の部分に介入するロギングなどのコードが配置されている どの業務コードが実行されるか。
2. ビジネス コードの実行前または実行後、いつ割り込むか。
3. 権限の確認、ログ記録など、スイッチイン後に行うべきこと。
# 絵で理解できます:
絵の中心となる用語 説明:
Pointcut: Pointcut は、ビジネス コードのどこに切り込む (つまり、アスペクトに織り込む) かを決定します。ポイントカットは、実行モードと注釈モードに分かれています。実行モード: パス式を使用して、アスペクトに組み込むクラスを指定できます 注釈モード: アノテーションで変更されたどのコードをアスペクトに組み込むかを指定できます。
アドバイス: 処理、処理タイミングや処理内容など。コンテンツの処理とは、アクセス許可の確認やログの記録など、何らかの処理を行うことを意味します。処理タイミングとは、処理内容がいつ実行されるかを指し、前処理(つまり業務コードが実行される前)、後処理(業務コードが実行された後)などに分けられます。
アスペクト: アスペクト、つまりポイントカットとアドバイス。
ジョイント ポイント:ジョイント ポイントは、プログラムの実行ポイントです。たとえば、メソッドの実行や例外の処理などです。 Spring AOP では、ジョインポイントは常にメソッドの実行を表します。
Weaving: Weaving は、動的プロキシを通じてターゲット オブジェクト メソッドのコンテンツを処理するプロセスです。
3. 実装手順
(1) アノテーション @Log をカスタマイズする (2) アスペクト クラスを作成し、@Log アノテーションが付けられたメソッドをインターセプトするカット ポイントを設定します. 渡されたパラメータをインターセプトし、ログを記録します (3) インターフェイスで @Log をマークします。
具体的な実装手順は次のとおりです:
1. AOP 依存関係を追加します
コードは次のとおりです (例):
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
2. ログの注釈をカスタマイズする
ログでは通常、注釈タイプのポイントカット式が使用されます。 create ログ アノテーション Spring コンテナがこのアノテーションを持つメソッドをスキャンすると、そのアノテーションが強化されます。
コードは次のとおりです (例):
@Target({ ElementType.PARAMETER, ElementType.METHOD }) // 注解放置的目标位置,PARAMETER: 可用在参数上 METHOD:可用在方法级别上 @Retention(RetentionPolicy.RUNTIME) // 指明修饰的注解的生存周期 RUNTIME:运行级别保留 @Documented public @interface Log { /** * 模块 */ String title() default ""; /** * 功能 */ public BusinessType businessType() default BusinessType.OTHER; /** * 是否保存请求的参数 */ public boolean isSaveRequestData() default true; /** * 是否保存响应的参数 */ public boolean isSaveResponseData() default true; }
3. アスペクト宣言
アスペクトクラスを宣言し、Spring コンテナに渡します。管理用。
コードは次のとおりです (例):
@Aspect @Component @Slf4j public class LogAspect { @Autowired private IXlOperLogService operLogService; /** * 处理完请求后执行 * @param joinPoint 切点 */ @AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult") public void doAfterReturnibng(JoinPoint joinPoint, Log controllerLog, Object jsonResult) { handleLog(joinPoint, controllerLog, null, jsonResult); } protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) { try { // 获取当前的用户 JwtUser loginUser = SecurityUtils.getLoginUser(); // 日志记录 XlOperLog operLog = new XlOperLog(); operLog.setStatus(0); // 请求的IP地址 String iP = ServletUtil.getClientIP(ServletUtils.getRequest()); if ("0:0:0:0:0:0:0:1".equals(iP)) { iP = "127.0.0.1"; } operLog.setOperIp(iP); operLog.setOperUrl(ServletUtils.getRequest().getRequestURI()); if (loginUser != null) { operLog.setOperName(loginUser.getUsername()); } if (e != null) { operLog.setStatus(1); operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000)); } // 设置方法名称 String className = joinPoint.getTarget().getClass().getName(); String methodName = joinPoint.getSignature().getName(); operLog.setMethod(className + "." + methodName + "()"); operLog.setRequestMethod(ServletUtils.getRequest().getMethod()); operLog.setOperTime(new Date()); // 处理设置注解上的参数 getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult); // 保存数据库 operLogService.save(operLog); } catch (Exception exp) { log.error("异常信息:{}", exp.getMessage()); exp.printStackTrace(); } } /** * 获取注解中对方法的描述信息 用于Controller层注解 * @param log 日志 * @param operLog 操作日志 * @throws Exception */ public void getControllerMethodDescription(JoinPoint joinPoint, Log log, XlOperLog operLog, Object jsonResult) throws Exception { // 设置操作业务类型 operLog.setBusinessType(log.businessType().ordinal()); // 设置标题 operLog.setTitle(log.title()); // 是否需要保存request,参数和值 if (log.isSaveRequestData()) { // 设置参数的信息 setRequestValue(joinPoint, operLog); } // 是否需要保存response,参数和值 if (log.isSaveResponseData() && StringUtils.isNotNull(jsonResult)) { operLog.setJsonResult(StringUtils.substring(JSON.toJSONString(jsonResult), 0, 2000)); } } /** * 获取请求的参数,放到log中 * @param operLog 操作日志 * @throws Exception 异常 */ private void setRequestValue(JoinPoint joinPoint, XlOperLog operLog) throws Exception { String requsetMethod = operLog.getRequestMethod(); if (HttpMethod.PUT.name().equals(requsetMethod) || HttpMethod.POST.name().equals(requsetMethod)) { String parsams = argsArrayToString(joinPoint.getArgs()); operLog.setOperParam(StringUtils.substring(parsams,0,2000)); } else { Map<?,?> paramsMap = (Map<?,?>) ServletUtils.getRequest().getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE); operLog.setOperParam(StringUtils.substring(paramsMap.toString(),0,2000)); } } /** * 参数拼装 */ private String argsArrayToString(Object[] paramsArray) { String params = ""; if (paramsArray != null && paramsArray.length > 0) { for (Object object : paramsArray) { // 不为空 并且是不需要过滤的 对象 if (StringUtils.isNotNull(object) && !isFilterObject(object)) { Object jsonObj = JSON.toJSON(object); params += jsonObj.toString() + " "; } } } return params.trim(); } /** * 判断是否需要过滤的对象。 * @param object 对象信息。 * @return 如果是需要过滤的对象,则返回true;否则返回false。 */ @SuppressWarnings("rawtypes") public boolean isFilterObject(final Object object) { Class<?> clazz = object.getClass(); if (clazz.isArray()) { return clazz.getComponentType().isAssignableFrom(MultipartFile.class); } else if (Collection.class.isAssignableFrom(clazz)) { Collection collection = (Collection) object; for (Object value : collection) { return value instanceof MultipartFile; } } else if (Map.class.isAssignableFrom(clazz)) { Map map = (Map) object; for (Object value : map.entrySet()) { Map.Entry entry = (Map.Entry) value; return entry.getValue() instanceof MultipartFile; } } return object instanceof MultipartFile || object instanceof HttpServletRequest || object instanceof HttpServletResponse || object instanceof BindingResult; } }
4. インターフェイスにマークを付けます
操作が行われるカスタム アノテーションをマークします。ログを記録する必要がある インターフェイス上のコードは次のとおりです (例):
@Log(title = "代码生成", businessType = BusinessType.GENCODE) @ApiOperation(value = "批量生成代码") @GetMapping("/download/batch") public void batchGenCode(HttpServletResponse response, String tables) throws IOException { String[] tableNames = Convert.toStrArray(tables); byte[] data = genTableService.downloadCode(tableNames); genCode(response, data); }
5. 実装の効果
関連する操作が実行されると、ログが記録されます。いくつかの基本情報が記録され、データ テーブルに保存されます。
以上がJava SpringBoot プロジェクトで操作ログをエレガントに実装するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

新しいテクノロジーは、両方の脅威をもたらし、Javaのプラットフォームの独立性を高めます。 1)Dockerなどのクラウドコンピューティングとコンテナ化テクノロジーは、Javaのプラットフォームの独立性を強化しますが、さまざまなクラウド環境に適応するために最適化する必要があります。 2)WebAssemblyは、Graalvmを介してJavaコードをコンパイルし、プラットフォームの独立性を拡張しますが、パフォーマンスのために他の言語と競合する必要があります。

JVMの実装が異なると、プラットフォームの独立性が得られますが、パフォーマンスはわずかに異なります。 1。OracleHotspotとOpenJDKJVMは、プラットフォームの独立性で同様に機能しますが、OpenJDKは追加の構成が必要になる場合があります。 2。IBMJ9JVMは、特定のオペレーティングシステムで最適化を実行します。 3. Graalvmは複数の言語をサポートし、追加の構成が必要です。 4。AzulzingJVMには、特定のプラットフォーム調整が必要です。

プラットフォームの独立性により、開発コストが削減され、複数のオペレーティングシステムで同じコードセットを実行することで開発時間を短縮します。具体的には、次のように表示されます。1。開発時間を短縮すると、1セットのコードのみが必要です。 2。メンテナンスコストを削減し、テストプロセスを統合します。 3.展開プロセスを簡素化するための迅速な反復とチームコラボレーション。

java'splatformentedencefacilitatesecodereusebyAllowingbyTeCodeCodeCodeCodeTorunonAnyPlatformm.1)DevelopersConcodeCodeOnceOnceOnconconsentEntentEntEntEntEntEntentPlatforms.2)維持化されたアスカデドは、NoeedReadedoesではありません

Javaアプリケーションのプラットフォーム固有の問題を解決するには、次の手順を実行できます。1。Javaのシステムクラスを使用して、システムプロパティを表示して実行中の環境を理解します。 2。ファイルクラスまたはjava.nio.fileパッケージを使用して、ファイルパスを処理します。 3。オペレーティングシステムの条件に応じてローカルライブラリをロードします。 4. VisualVMまたはJProfilerを使用して、クロスプラットフォームのパフォーマンスを最適化します。 5.テスト環境が、Dockerコンテナ化を通じて生産環境と一致していることを確認してください。 6. githubactionsを使用して、複数のプラットフォームで自動テストを実行します。これらの方法は、Javaアプリケーションでプラットフォーム固有の問題を効果的に解決するのに役立ちます。

クラスローダーは、統一されたクラスファイル形式、動的読み込み、親代表団モデル、プラットフォーム非依存バイトコードを通じて、さまざまなプラットフォーム上のJavaプログラムの一貫性と互換性を保証し、プラットフォームの独立性を実現します。

Javaコンパイラによって生成されたコードはプラットフォームに依存しませんが、最終的に実行されるコードはプラットフォーム固有です。 1。Javaソースコードは、プラットフォームに依存しないバイトコードにコンパイルされます。 2。JVMは、特定のプラットフォームのバイトコードをマシンコードに変換し、クロスプラットフォーム操作を保証しますが、パフォーマンスは異なる場合があります。

マルチスレッドは、プログラムの応答性とリソースの利用を改善し、複雑な同時タスクを処理できるため、最新のプログラミングで重要です。 JVMは、スレッドマッピング、スケジューリングメカニズム、同期ロックメカニズムを介して、異なるオペレーティングシステム上のマルチスレッドの一貫性と効率を保証します。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

MantisBT
Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

EditPlus 中国語クラック版
サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

ZendStudio 13.5.1 Mac
強力な PHP 統合開発環境

Safe Exam Browser
Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)
