一、Mavenプロジェクトの依存関係設定
pom.xmlファイルにSpringコンテキストとAspectJ Weaverの依存関係を追加します。これらのライブラリはAOP機能の実装に必須です。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>spring-aop-demo</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.23</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.9</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
二、Spring設定ファイル
aop設定を有効にするため、XML名前空間にaop名前空間を追加します。bean要素を使用して、增强対象のクラスとAdviceクラスをコンテナに登録します。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--增强対象のサービスクラス-->
<bean id="targetBean" class="com.example.service.impl.MemberServiceImpl"></bean>
<!--Adviceを提供するクラス-->
<bean id="loggingAspect" class="com.example.aspect.LoggingAdvice"></bean>
<aop:config>
<aop:pointcut id="executionPoint"
expression="execution(public void com.example.service.impl.MemberServiceImpl.deleteMember())"/>
<aop:aspect id="logAspect" ref="loggingAspect">
<aop:before method="logBefore" pointcut-ref="executionPoint"></aop:before>
<aop:around method="logAround"
pointcut="execution(public String com.example.service.impl.MemberServiceImpl.getMemberInfo())"></aop:around>
</aop:aspect>
</aop:config>
</beans>
切入点式では、メソッドのシグネチャパターンを指定することで、增强を適用する範囲を定義できます。
三、サービスインターフェース
ビジネスロジックを定義するインターフェースです。AOPはこのインターフェースを実装したクラスに增强を適用します。
package com.example.service;
public interface MemberService {
void updateMember(String name);
String getMemberInfo();
void deleteMember();
}
四、サービス実装クラス
インターフェースを実装する具体的なビジネスロジッククラスです。このクラスのメソッドがAOPによって增强されます。
package com.example.service.impl;
import com.example.service.MemberService;
public class MemberServiceImpl implements MemberService {
@Override
public void updateMember(String name) {
System.out.println("メンバー更新: " + name);
}
@Override
public String getMemberInfo() {
System.out.println("メンバー情報取得中...");
return "田中太郎";
}
@Override
public void deleteMember() {
System.out.println("メンバー削除処理");
}
}
五、Adviceクラス
AOPの核心となるクラスです。メソッドの実行前後に処理を挟み込むことができます。ProceedingJoinPointを使用して、环绕通知では元のメソッドの実行タイミングを制御できます。
package com.example.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
public class LoggingAdvice {
public void logBefore() {
System.out.println("=== 処理開始前にログ出力 ===");
}
public Object logAround(ProceedingJoinPoint point) {
Object result = null;
try {
System.out.println("【前置】メソッド実行前処理");
Object[] parameters = point.getArgs();
result = point.proceed(parameters);
System.out.println("【後置】 정상実行完了");
} catch (Throwable error) {
System.out.println("【異常】例外が発生: " + error.getMessage());
} finally {
System.out.println("【最終】終了処理を実行");
}
return result;
}
}
六、動作確認
Springコンテナからbeanを取得し、Proxyオブジェクトを通じてメソッドを呼び出すことでAOPの動作を確認できます。
package com.example.test;
import com.example.service.MemberService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AopVerification {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
MemberService service = (MemberService) context.getBean("targetBean");
service.getMemberInfo();
}
}
七、AOPの概念
AOP(Aspect-Oriented Programming)は、既存のメソッドの実装を変更することなく、機能拡張を実現するプログラミングパラダイムです。Springフレームワークでは、動的Proxyを使用してこの機能を実現しています。 비즈니스 로직과 공통機能を分離することで、コードの再利用性を高め、関心の分離を実現できます。