자바 프로그래머 는 어 리 석 은 새 부터 초보 의 (74) 까지 Spring (6) spring 의 AOP 기본 개념 과 배치 에 대해 상세히 이야기 했다.

10995 단어 spring
우선 공식 문서 에서 우리 에 게 준 AOP 에 관 한 개념 적 인 단어 들 에 대한 설명 을 살 펴 보 자.
절단면 (Aspect): 하나의 관심 사 모듈 화, 이 관심 사 는 여러 대상 을 가로로 자 를 수 있 습 니 다.사무 관 리 는 J2EE 응용 프로그램 에서 횡단 관심 사 에 관 한 좋 은 예 이다.SpringAOP 에서 절단면 은 패턴 기반) 또는 Aspect 주해 방식 으로 이 루어 질 수 있 습 니 다.쉽게 말 하면 우리 가 넣 은 절단면 류 (예 를 들 어 log 류) 는 이렇게 이해 할 수 있다.
연결 점 (Joinpoint): 프로그램 이 실행 되 는 과정 에서 특정한 점, 예 를 들 어 특정한 방법 이 호출 되 었 을 때 나 이상 을 처리 할 때.SpringAOP 에서 하나의 연결 점 은 항상 하나의 방법의 실행 을 나타 낸다.쉽게 말 하면 접점 을 넣 은 그 점.
알림 (Advice): 절단면 의 특정한 연결 점 에서 실행 되 는 동작 입 니 다.'around', 'before', 'after' 등 다양한 유형의 알림 (알림 의 유형 은 뒷부분 에서 토론 합 니 다) 이 포함 되 어 있 습 니 다.많은 AOP 프레임 워 크 (Spring 포함) 는 차단기 로 알림 모델 을 만 들 고 연결 점 을 중심 으로 하 는 차단기 체인 을 유지 합 니 다.
접점 (Pointcut): 연결 점 과 일치 하 는 단언 입 니 다.알림 은 접점 표현 식 과 연결 되 어 있 으 며, 이 접점 을 만족 시 키 는 연결 점 에서 실 행 됩 니 다 (예 를 들 어 특정한 이름 을 실행 하 는 방법 을 실행 할 때).접점 표현 식 이 연결 점 과 어떻게 일치 하 는 지 는 AOP 의 핵심 입 니 다. Spring 결 성 은 AspectJ 접점 문법 을 사용 합 니 다.
도입 (Introduction): 하나의 유형 에 추가 적 인 방법 이나 속성 을 설명 하 는 데 사 용 됩 니 다.Spring 은 대리 대상 에 새로운 인터페이스 (및 대응 하 는 실현) 를 도입 할 수 있 습 니 다.예 를 들 어, 캐 시 메커니즘 을 간소화 하기 위해 bean 을 IsModified 인 터 페 이 스 를 도입 할 수 있 습 니 다.
대상 (TargetObject): 하나 이상 의 절단면 에 의 해 알려 진 대상.알림 대상 이 라 고도 합 니 다.SpringAOP 가 실 행 될 때 대 리 를 통 해 이 루어 진 이상 이 대상 은 영원히 대리 (proxied) 대상 이다.
AOP 에이전트 (AOP Proxy): AOP 프레임 워 크 가 만 든 대상 은 절단면 계약 (예 를 들 어 알림 방법 실행 등) 을 실현 하 는 데 사 용 됩 니 다.Spring 에서 AOP 에이 전 트 는 JDK 동적 에이전트 나 CGLIB 에이전트 가 될 수 있다.
짜 기 (Weaving): 다른 프로그램 형식 이나 대상 에 절단면 을 연결 하고 알려 진 대상 을 만 듭 니 다.이것 은 컴 파일 할 때 (예 를 들 어 AspectJ 컴 파일 러 사용) 클래스 로 딩 할 때 와 실행 할 때 완성 할 수 있 습 니 다.Spring 은 다른 순수 자바 AOP 프레임 워 크 와 마찬가지 로 실행 중 직 입 이 완료 되 었 습 니 다.
알림 종류:
사전 알림 (Beforadvice): 특정한 연결 점 전에 실 행 된 알림 이지 만 이 알림 은 연결 점 이전의 실행 절 차 를 막 을 수 없습니다 (이상 을 던 지지 않 는 한).
나중에 알림 (Aftereturningadvice): 특정한 연결 점 이 정상적으로 완 료 된 후에 실 행 된 알림: 예 를 들 어 하나의 방법 이 이상 을 던 지지 않 고 정상적으로 돌아 갑 니 다.
이상 알림 (Afterthrowingadvice): 이상 하 게 종료 할 때 실행 되 는 알림 을 던 집 니 다.
최종 알림 (after (finally) advice): 특정한 연결 점 이 종료 되 었 을 때 실 행 된 알림 (정상 적 인 복귀 든 이상 한 종료 든).
서 라운드 알림 (Around Advice): 방법 호출 과 같은 연결 점 을 둘 러 싼 알림 입 니 다.이것 은 가장 강력 한 알림 유형 이다.서 라운드 알림 은 방법 호출 전후 에 사용자 정의 행동 을 완성 할 수 있 습 니 다.연결 점 을 계속 실행 하거나 자신의 반환 값 을 직접 되 돌려 주거 나 이상 을 던 져 서 실행 을 끝 낼 지 선택 합 니 다.
서 라운드 알림 은 가장 자주 사용 하 는 알림 유형 입 니 다.AspectJ 와 마찬가지 로 Spring 은 모든 유형의 알림 을 제공 합 니 다. 가능 한 한 간단 한 알림 유형 을 사용 하여 필요 한 기능 을 실현 하 는 것 을 추천 합 니 다.예 를 들 어 캐 시 를 업데이트 하 는 방법 이 필요 하 다 면 서 라운드 알림 이 아 닌 서 라운드 알림 을 사용 하 는 것 이 좋 습 니 다. 서 라운드 알림 도 같은 일 을 할 수 있 습 니 다.가장 적합 한 알림 형식 으로 프로 그래 밍 모델 을 간단 하 게 만 들 고 잠재 적 인 오 류 를 피 할 수 있 습 니 다.예 를 들 어 JoinPoint 에서 알림 을 둘 러 싼 proced () 방법 을 호출 하지 않 아 도 호출 에 문제 가 없 을 것 입 니 다.
springAOP 의 실현
spring 2.5 에서 자주 사용 하 는 AOP 구현 방식 은 두 가지 가 있다.첫 번 째 는 xml 프로필 방식 을 바탕 으로 하 는 것 이 고, 두 번 째 는 주해 방식 을 바탕 으로 하 는 것 이다.다음은 구체 적 인 예시 로 이 두 가지 방식 의 사용 을 설명 한다.다음 에 우리 가 사용 할 인 스 턴 스 는 등록 입 니 다. 사용자 이름과 비밀번호 가 있 습 니 다. 저 희 는 AOP 를 이용 하여 사용자 가 등록 할 때 데 이 터 를 저장 하기 전과 그 후에 이상 을 던 질 때 이 를 실현 합 니 다. 이런 상황 에서 로 그 를 추가 합 니 다.여기 서 우 리 는 AOP 만 설명 하기 때문에 나 는 핵심 코드 만 붙 이 고 상 관 없 는 것 은 붙 이지 않 는 다.
우선 업무 논리 서비스 층 을 살 펴 보 겠 습 니 다.
/**
 * RegisterService    
 * @author     */
public class RegisterServiceImpl implements RegisterService {
    private  RegisterDao registerDao;
    public RegisterServiceImpl() {}
    /**          */
    public RegisterServiceImpl(RegisterDao  registerDao){
        this.registerDao =registerDao;
    }
    public void save(String loginname, String password) {
        registerDao.save(loginname, password);
        throw new RuntimeException("        。。。。");
    }
      /** set   */
    public void setRegisterDao(RegisterDao registerDao) {
        this.registerDao = registerDao;
}}

업무 시스템 에 있어 RegisterServiceImpl 류 는 목표 실현 류 로 그의 업무 방법, 예 를 들 어 save () 방법의 전후 나 코드 에 이상 이 생 길 수 있 는 곳 은 모두 AOP 의 연결 점 이다.
다음은 로그 서비스 클래스 의 코드 입 니 다.
/**
 *      
 * @author    
 */
public class LogAspect {
    //                   org.aspectj.lang.JoinPoint   
    public void before(JoinPoint call) {
        //           
        String className = call.getTarget().getClass().getName();
        //               
        String methodName = call.getSignature().getName();
        System.out.println("    :" + className + "  " + methodName + "     ");
    }
    public void afterReturn() {
        System.out.println("    :       ");
    }
    public void after(){
        System.out.println("    :             ,      ");
    }
    public void afterThrowing() {
        System.out.println("       :         ");
    }
    //                    org.aspectj.lang.ProceedingJoinPoint  
    public Object doAround(ProceedingJoinPoint call) throws Throwable {
        Object result = null;
        this.before(call);//       
        try {
            result = call.proceed();
            this.afterReturn(); //       
        } catch (Throwable e) {
            this.afterThrowing();  //          
            throw e;
        }finally{
            this.after();  //       
        }
        return result;
    }
}

이 종 류 는 업무 서비스 류 에 속 합 니 다. 만약 에 AOP 의 용어 로 말 하면 절단면 류 이 고 많은 통 지 를 정의 합 니 다.Before (), after Return (), after (), after Throwing () 등 방법 은 모두 알림 입 니 다.
다음은 구체 적 인 설정 을 살 펴 보 겠 습 니 다. 먼저 보 겠 습 니 다.
< 1 >. xml 프로필 을 기반 으로 한 AOP 구현: 이 방식 은 AOP 를 구현 할 때 4 단계 가 있 습 니 다.
<?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-2.5.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd>
    <bean id="registerDaoImpl" class="com.zxf.dao.RegisterDaoImpl"/>
    <bean id="registerService" class="com.zxf.service.RegisterServiceImpl">
        <property name=" registerDaoImpl " ref=" RegisterDaoImpl "/>
    </bean>
    <!--       -->
    <bean id="logAspectBean" class="com.zxf.aspect.LogAspect"/>
    <!--  1 : AOP    -->
    <aop:config>
        <!--  2 :       -->
        <aop:aspect id="logAspect" ref="logAspectBean">
            <!--  3 :     ,         -->
            <aop:pointcut id="allMethod" 
                expression="execution(* com.zxf.service.*.*(..))"/> 
            <!--  4 :       -->
            <aop:before method="before" pointcut-ref="allMethod" />
            <!--  4 :       -->
            <aop:after-returning method="afterReturn" pointcut-ref="allMethod"/>
            <!--  4 :       -->
            <aop:after method="after" pointcut-ref="allMethod"/>
            <!--  4 :          -->
            <aop:after-throwing method="afterThrowing" pointcut-ref="allMethod"/>
            <!--  4 :       -->
            <!-- 
            <aop:around method="doAround" pointcut-ref="allMethod" />
             -->
        </aop:aspect>
    </aop:config>
</beans>

상기 설정 은 삽입 점 에 대해 전치, 후 치, 최종, 그리고 이상 을 던 진 후 알림 을 적용 합 니 다.이렇게 레지스터 서비스 Impl 류 의 save () 방법 을 테스트 할 때 컨트롤 러 는 다음 과 같은 결 과 를 출력 합 니 다.
사전 알림: com. zxf. service. RegisterServiceImpl 류 의 save 방법 이 시작 되 었 습 니 다.
MySQL 의 RegisterDao 구현 에 대한 save () 방법 입 니 다.
후방 알림: 방법 이 정상적으로 끝 났 습 니 다.
최종 알림: 방법 이 정상적으로 실행 되 었 든 안 되 었 든 반드시 돌아 올 것 입 니 다.
다음은 두 번 째 설정 방식 을 살 펴 보 겠 습 니 다.
< 2 > 주석 기반 AOP 구현
먼저 절단면 으로 사용 할 LogAnnotationAspect 를 만 들 고 이 종 류 를 spring 설정 파일 에 설정 합 니 다.
spring 2.0 이후 JDK 5.0 의 주석 Annotation 지원 을 도입 하여 AspectJ 의 주석 기반 절단면 지원 을 제공 하여 AOP 설정 을 더욱 간소화 하 였 습 니 다.구체 적 인 절 차 는 두 단계 다.
Spring 설정 파일 은 다음 과 같 습 니 다.
<?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-2.5.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd>
    <bean id="registerDao" class="com.zxf.dao.RegisterDaoImpl"/>
    <bean id="registerService" class="com.zxf.service.RegisterServiceImpl">
        <property name="registerDao" ref="registerDao"/>
    </bean>
    <!--       Spring      -->
    <bean id="logAspectBean" class="com.zxf.aspect.LogAnnotationAspect"/>
    <!--   spring AspectJ      -->
    <aop:aspectj-autoproxy/>
</beans>

이것 은 그 절단면 류 LogAnnotationAspect 입 니 다.
/**
 *      
 */
@Aspect  //     
public class LogAnnotationAspect {
    @SuppressWarnings("unused")
    //     ,      ,              id
    @Pointcut("execution(* com.zxf.service.*.*(..))")
    private void allMethod(){}
    //                       
    @Before("execution(* com. zxf.service.*.*(..))")
    public void before(JoinPoint call) {
        String className = call.getTarget().getClass().getName();
        String methodName = call.getSignature().getName();
        System.out.println("【  -    】:" + className + "  " 
                + methodName + "     ");
    }
    //              
    @AfterReturning("allMethod()")
    public void afterReturn() {
        System.out.println("【  -    】:       ");
    }
    //      
    @After("allMethod()")
    public void after(){
        System.out.println("【  -    】:             ," 
                + "      ");
    }
    //         
    @AfterThrowing("allMethod()")
    public void afterThrowing() {
        System.out.println("【  -       】:         ");
    }
    //      
    //@Around("allMethod()")
    public Object doAround(ProceedingJoinPoint call) throws Throwable{
        Object result = null;
        this.before(call);//       
        try {
            result = call.proceed();
            this.afterReturn(); //       
        } catch (Throwable e) {
            this.afterThrowing();  //          
            throw e;
        }finally{
            this.after();  //       
        }
        return result;
    }
}

비고: 출력 결 과 는 앞의 것 과 같 습 니 다.

좋은 웹페이지 즐겨찾기