English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Spring AOP AspectJ 주석 예제

Spring 프레임워크Spring을 기반으로 사용하는 것을 권장합니다 1.2오래된 스타일 dtd의 AOP 구현에 사용됩니다 Spring AspectJ AOP 구현사용하기 쉽습니다。

Spring AOP AspectJ 구현을 사용하는 방법이 두 가지 있습니다:

주석을 통해: 여기서 배울 것입니다。 XML 구성(모델 기반): 다음 페이지에서 배울 것입니다。

주의: aop 개념 및 장점 등을 이해하려면 여기를 방문하세요. AOP 개념 강의

Spring AspectJ AOP 구현은 다양한 주석을 제공합니다:

@Aspect 이 클래스를 aspect로 선언합니다. @Pointcut 점검표현식을 선언합니다.

권장사를 생성하는 주석은 다음과 같습니다:

@Before before 권장사를 선언했습니다. 실제 메서드 호출 전에 적용됩니다。 @After after 권장사를 선언했습니다. 실제 메서드 호출 후에 결과 값이 반환되기 전에 적용됩니다。 @AfterReturning returning 권장사를 선언했습니다. 실제 메서드 호출 후에 결과 값이 반환되기 전에 적용됩니다. 하지만 권장사에서 결과 값을 가져올 수 있습니다。 @Around around 권장사를 선언했습니다. 실제 메서드 호출 전과 후에 적용됩니다。 @AfterThrowing throws 권장사를 선언했습니다. 실제 메서드가 예외를 발생시키면 이 메서드가 적용됩니다。

점검 이해하기

점검은 Spring AOP의 표현어입니다。

@Pointcut 주석은 점검을 정의하는 데 사용됩니다. 점검표현식의 이름을 통해 점검을 참조할 수도 있습니다. 간단한 점검표현식 예제를 보겠습니다。

@Pointcut("execution(")* Operation.*(..))")
private void doSomething() {}

점검표현식의 이름은 doSomething()입니다. 반환형에 관계없이 모든 Operation 클래스의 메서드에 적용됩니다。

점검어서 이해해보세요

다음 예제를 통해 점검어서 이해해보겠습니다:

@Pointcut("execution(public" * *(..))")

그것은 모든 공개 메서드에 적용됩니다。


@Pointcut("execution(public Operation."}*(..))")

그것은 Operation 클래스의 모든 공개 메서드에 적용됩니다。


@Pointcut("execution(")* Operation.*(..))")

그것은 Operation 클래스의 모든 메서드에 적용됩니다。


@Pointcut("execution(public Employee.set"*(..))")

그것은 Employee 클래스의 모든 공개 설정 메서드에 적용됩니다。


@Pointcut("execution(int Operation."}*(..))")

이는 모든 int 값을 반환하는 Operation 클래스 메서드에 적용됩니다.


1、@Before 예제

실제 비즈니스 로직 메서드 전에 AspectJ Before Advice를 적용합니다. 여기서는 변환, 인증 등의 작업을 수행할 수 있습니다.

创建一个包含实际业务逻辑的类。

파일: Operation.java

package com.w;3codebox;
public class Operation{
	public void msg(){System.out.println("msg method invoked");}
	public int m(){System.out.println("m method invoked");return 2;}
	public int k(){System.out.println("k method invoked");return 3;}
}

지금, 조언에 포함된 클래스를 생성합니다.

파일: TrackOperation.java

package com.w;3codebox;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class TrackOperation{
	@Pointcut("execution(")* Operation.*(..))")
	public void k(){}//포인트컷 이름
	@Before("k()")//before 알림에 컷포인트를 적용합니다
	public void myadvice(JoinPoint jp)//it is advice (before advice)
	{
		System.out.println("추가적인 관심사");
		//System.out.println("메서드 시그니처: "}  + jp.getSignature());
	}
}

bean을 정의하는 applicationContext.xml 파일을 생성합니다.

파일: applicationContext.xml

<?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 
	   http://www.springframework.org/schema/beans/spring-beans.xsd 
	   http://www.springframework.org/schema/aop 
	   http://www.springframework.org/schema/aop/spring-aop.xsd">
	<bean id="opBean" class="com.w3codebox.Operation">	</bean>
	<bean id="trackMyBean" class="com.w3codebox.TrackOperation"></bean>
	<bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"></bean>
</beans>

지금, 실제 메서드로 지칭하겠습니다.

파일: Test.java

package com.w;3codebox;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test{
	public static void main(String[] args){
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		Operation e = (Operation) context.getBean("opBean");
		System.out.println("calling msg...");
		e.msg();
		System.out.println("calling m...");
		e.m();
		System.out.println("calling k...");
		e.k();
	}
}

출력

msg() 호출 중...
추가적인 관심사
msg() 메서드 호출됨
calling m...
추가적인 관심사
m() method invoked
calling k...
추가적인 관심사
k() method invoked

msg(), m(), k() 메서드 호출 전에도 다른 문제가 표시되는 것을 볼 수 있습니다.

아래와 같이 포인트컷 표현식을 변경하면:

@Pointcut("execution(")* Operation.m*(..))")

이제 Operation 클래스에서 m으로 시작하는 메서드에 더 많이 집중할 것입니다. 출력은 다음과 같습니다:

msg() 호출 중...
추가적인 관심사
msg() 메서드 호출됨
calling m...
추가적인 관심사
m() method invoked
calling k...
k() method invoked

이제 k() 메서드 호출 전에 다른 문제가 출력되지 않는 것을 볼 수 있습니다.


2、@After 예제

실제 비즈니스 로직 메서드 호출 후에 after 추천을 적용한 AspectJ를 사용하여 로그 유지, 보안, 알림 등을 할 수 있습니다.

이곳에서는 다음과 같이 가정합니다 Operation.java applicationContext.xml Test.java 文件与@Before示例中给出的文件相同。

파일: TrackOperation.Java
package com.w;3codebox;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class TrackOperation{
	@Pointcut("execution(")* Operation.*(..))")
	public void k(){}//포인트컷 이름
	@After("k()")//추천 후에 측면을 적용하는 포인트컷
	public void myadvice(JoinPoint jp)//추천 후에 추천(it는 추천 후)
	{
		System.out.println("추가적인 관심사");
		//System.out.println("메서드 시그니처: "}  + jp.getSignature());
	}
}
 

출력

msg() 호출 중...
msg() 메서드 호출됨
추가적인 관심사
calling m...
m() method invoked
추가적인 관심사
calling k...
k() method invoked
추가적인 관심사
 

msg(), m(), k() 메서드 호출 후에도 다른 문제가 나타나는 것을 볼 수 있습니다.


3、@AfterReturning 예제

추천 후 사용하여 추천에서 결과를 얻을 수 있습니다。

다음과 같은 내용을 포함한 클래스 비즈니스 로직을 생성합니다。

파일: Operation.java

package com.w;3codebox;
public class Operation{
	public int m(){System.out.println("m() 메서드 호출됨");return 2;}
	public int k(){System.out.println("k() 메서드 호출됨");return 3;}
}
 

추천 후 포함된 측면 클래스를 생성합니다。

파일: TrackOperation.java

package com.w;3codebox;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class TrackOperation{
	@AfterReturning(
		      pointcut = "execution(* Operation.*(..))",
		      returning= "result")
		      
	public void myadvice(JoinPoint jp, Object result)//추천(it는 추천 후)
	{
		System.out.println("추가적인 관심사");
		System.out.println("메서드 시그니처: "}  + jp.getSignature());
		System.out.println("추천 결과: ")+result);
		System.out.println("end of after returning advice...");
	}
}
 

파일: applicationContext.xml

@Before 권장 예제에서 제공된

파일: Test.java

현재 실제 메서드를 호출하는 Test 클래스를 생성합니다。

package com.w;3codebox;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test{
	public static void main(String[] args){
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		Operation e = (Operation) context.getBean("opBean");
		System.out.println("calling m...");
		System.out.println(e.m());
		System.out.println("calling k...");
		System.out.println(e.k());
	}
}
 

출력

calling m...
m() method invoked
추가적인 관심사
Method Signature: int com.w3codebox.Operation.m()
Result in advice: 2
end of after returning advice...
2
calling k...
k() method invoked
추가적인 관심사
Method Signature: int com.w3codebox.Operation.k()
Result in advice: 3
end of after returning advice...
3
 

您可以看到返回值已打印两次,一次是由TrackOperation类打印,第二次是Test类。


4、@Around示例

围绕通知的AspectJ在调用实际的业务逻辑方法之前和之后都得到应用。

在这里,我们是假设   applicationContext.xml 文件与@Before示例中给出的文件相同。

创建一个包含实际业务逻辑的类。

파일: Operation.java

package com.w;3codebox;
public class Operation{
	public void msg(){System.out.println("msg() is invoked");}
	public void display(){System.out.println("display() is invoked");}
}
 

创建包含围绕建议的方面类。

您需要在advice方法中传递   PreceedingJoinPoint 引用,以便我们可以通过调用proce来进行请求()方法。

파일: TrackOperation.java

package com.w;3codebox;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class TrackOperation
{
	@Pointcut("execution(")* Operation.*(..))")
	public void abcPointcut(){}
	@Around("abcPointcut()")
	public Object myadvice(ProceedingJoinPoint pjp) throws Throwable 
	{
		System.out.println("실제 메서드 호출 전 추가적인 고려사항");
		Object obj = pjp.proceed();
		System.out.println("실제 메서드 호출 후 추가적인 고려사항");
		obj을 반환합니다;
	}
}
 

파일: Test.java

현재 실제 메서드를 호출하는 Test 클래스를 생성합니다。

package com.w;3codebox;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test{
	public static void main(String[] args){
		ApplicationContext context = new classPathXmlApplicationContext("applicationContext.xml");
		Operation op = (Operation) context.getBean("opBean");
		op.msg();
		op.display();
	}
}
 

출력

실제 메서드 호출 전 추가적인 고려사항
msg()가 호출됨
실제 메서드 호출 후 추가적인 고려사항
실제 메서드 호출 전 추가적인 고려사항
display()가 호출됨
실제 메서드 호출 후 추가적인 고려사항
 

msg()와 메서드를 호출하기 전과 후에도 다른 문제를 출력할 수 있습니다.


5、@AfterThrowing 예제

after throw 조언을 사용하여 TrackOperation 클래스에서 예외를 출력할 수 있습니다. AspectJ AfterThrowing 조언의 예제를 보겠습니다.

비즈니스 로직을 포함한 클래스를 생성합니다.

파일: Operation.java

package com.w;3codebox;
public class Operation{
	public void validate(int age) throws Exception{
	if(age<18){
		throw new ArithmeticException("유효하지 않은 나이입니다.");
	}
	else{
		System.out.println("감사합니다. 투표에 참여해 주셨습니다.");
	}
	}
}
 

추가적인 advice가 발생한 후 포함된 aspect 클래스를 생성합니다.

여기서는 Throwable 참조를 전달하여 이곳에서 예외를 캡처할 수 있도록 해야 합니다.

파일: TrackOperation.java

package com.w;3codebox;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class TrackOperation{
	@AfterThrowing(
		      pointcut = "execution(* Operation.*(..))",
		      throwing = "error")
		      
	public void myadvice(JoinPoint jp, Throwable error)//it is advice
	{
		System.out.println("추가적인 관심사");
		System.out.println("메서드 시그니처: "}  + jp.getSignature());
		System.out.println("예외는: "}+error);
		System.out.println("advice throwing 후의 끝...");
	}
}
 

파일: applicationContext.xml

@Before 권장 예제에서 제공된

파일: Test.java

현재 실제 메서드를 호출하는 Test 클래스를 생성합니다。

package com.w;3codebox;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test{
	public static void main(String[] args){
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		Operation op = (Operation) context.getBean("opBean");
		System.out.println("validate 호출...");
		try{
			op.validate(19);
		}catch(Exception e){System.out.println(e);}
		System.out.println("다시 validate 호출...");
		try{
		    op.validate(11);
		}catch(Exception e){System.out.println(e);}
	}
}
 

출력

validate 호출...
투표에 감사합니다
다시 validate 호출...
추가적인 관심사
메서드 서명: void com.w3codebox.Operation.validate(int)
예외는: java.lang.ArithmeticException: 무효한 나이
throwing 조언 후 끝...
java.lang.ArithmeticException: 무효한 나이