Spring AOP 의 강화

7885 단어 springAOPjdkxmlbean
Spring AOP 의 학습 을 계속 하 는 것 은 알다 시 피 op 의 매력 은 바로 방법 전후 에 차단 작용 을 하여 우리 가 횡단 논리 코드 를 정의 할 수 있 도록 하 는 것 이다.강 화 는 크게 5 가지 로 나 뉜 다. 선행 강화 (즉, 목표 방법 이 호출 되 기 전에 차단 하 는 것), 선행 강화 (즉, 목표 방법 이 호출 된 후에 차단 하 는 것), 이상 강화 (즉, 목표 방법 이 던 진 후에 차단 하 는 것), 소개 강화 이다.(이것 은 특수 한 증강 입 니 다. 목표 클래스 에 속성 과 방법 을 추가 할 수 있 습 니 다. 차단 을 통 해 하나의 인 터 페 이 스 를 정의 하여 목표 에이전트 로 하여 금 이 인 터 페 이 스 를 실현 하 게 합 니 다. 연결 점 은 클래스 등급 입 니 다). 앞의 세 가지 증강 은 방법 등급 입 니 다. 상기 네 가지 증강 인 터 페 이 스 는 Spring 정의 이 고 서 라운드 증강 (목표 방법 전후 차단) 만 사용 합 니 다.AOP 연맹 이 정의 하 는 인터페이스 입 니 다. 사실 aop 증강 은 간단 합 니 다. 이러한 증강 인 터 페 이 스 를 실현 함으로써 이 인 터 페 이 스 를 실현 하 는 방법 에서 횡 절 논 리 를 정의 한 다음 에 spring 프로필 을 설정 하면 증강 을 목표 방법 에 포함 시 킬 수 있 습 니 다.
 
우선, 선행 증강 을 예 로 들 면, 우리 가 식당 에 가면 종업원 이 먼저 고객 을 환영 한 다음 에 우 리 를 위해 서 비 스 를 제공 할 것 이라는 것 을 모두 가 알 고 있다.
Waiter 클래스:
package com.me.services;

public interface Waiter {
	void greetTo(String name);
	void serveTo(String name);
}

 지금 우 리 는 훈련 이 부족 한 웨이터 의 서비스 상황 을 살 펴 보 자.
package com.me.services.imp;

import com.me.services.Waiter;

public class LuceyWaiter implements Waiter {

	public void greetTo(String name) {
		System.out.println("greet to "+name);
	}

	public void serveTo(String name) {
		System.out.println("server "+name);
	}

}

루 시 는 말없이 고객 앞 에 다가 가 서 비 스 를 제공 하려 면 우 리 는 모든 웨이터 를 규범화 시 키 고 서비스 하기 전에 예절 용 어 를 사용 해 야 한다.
package com.me.advice;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

public class GreetingBeforeAdvice implements MethodBeforeAdvice {

	public void before(Method method, Object[] args, Object obj)
			throws Throwable {
		String clientName = args[0].toString();
		System.out.println("How are you,"+clientName+"!");
	}

}

 org. springframework. aop. MethodBefore Advice 인 터 페 이 스 를 실현 하 는 before 방법 으로 논리 코드 를 정의 합 니 다. before 의 세 가지 매개 변 수 는 목표 방법, 목표 방법의 매개 변수 목록, 목표 인 스 턴 스 를 대표 합 니 다.
대상 도 있 고, 강화 도 있 습 니 다. 그 다음 에 증강 직 입 된 대상 을 어떻게 대리 로 만 듭 니까? 지난번 블 로 그 는 spring 의 대리 체 제 를 썼 습 니 다. JDK 와 CGLib 두 가지 방식 으로 동적 으로 대 리 를 만 들 수 있다 는 것 을 알 고 있 습 니 다. 하지만 코드 가 너무 번 거 로 워 서 지정 한 인 터 페 이 스 를 사용자 정의 해 야 합 니 다. 간단 한 방법 이 있 습 니까? 물론, spring 은Proxy Factory Bean 을 제공 합 니 다. 위 에서 JDK, CGLib 를 통 해 복잡 한 작업 을 대리 할 수 있 도록 도와 주 었 습 니 다. 우 리 는 spring 에 설정 만 하면 직 입 작업 을 완성 할 수 있 습 니 다. ^ - ^
<beans
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
	<!--          -->
	<bean id="target" class="com.me.services.imp.LuceyWaiter"></bean>
	<!--     ,                 ,            -->
	<bean id="greetAdvice" class="com.me.advice.GreetingBeforeAdvice"></bean>
	<!--   ProxyFactoryBean     -->
	<bean id="waiter" class="org.springframework.aop.framework.ProxyFactoryBean">
	<!--         ,        -->		
		<property name="proxyInterfaces" value="com.me.services.Waiter"/>
		<property name="target" ref="target"/>
		<!--          0     -->
		<property name="interceptorNames">
			<list>
				<value>greetAdvice</value>
			</list>
		</property>
	</bean>
</beans>

Proxy Factory Bean 의 작업 원 리 는 나중에 쓸 것 입 니 다. 그러나 자주 사용 하 는 설정 속성 몇 가 지 를 더 알 아야 합 니 다. 위의 속성 을 제외 하고 singleton: 프 록 시가 하나의 인 스 턴 스 인지, 기본 true 인지 되 돌려 줍 니 다.
optimize: true 로 설정 되 었 을 때 CGLib 프 록 시 를 강제로 사용 합 니 다. 단일 인 스 턴 스 에 대해 서 는 true 를 추천 하지만, 역할 영역 유형의 프 록 시 에 대해 서 는 false 를 추천 합 니 다.
proxy TargetClass: 클래스 에이전트 (인터페이스 에 대한 에이전트 가 아 닌) 를 true 로 설정 하고 CGLib 프 록 시 를 사용 할 지 여부 입 니 다. 물론 true 로 설정 하면 proxy Interfaces 속성 을 설정 할 필요 가 없습니다. 설정 을 즉시 해도 무 시 됩 니 다. 다음 테스트 코드 를 사용 하 겠 습 니 다.
package com.me.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.me.services.Waiter;

public class TestBeforeAdvice {

	public static void main(String[] args) {
		ApplicationContext cxt = new ClassPathXmlApplicationContext("applicationContext.xml");
        Waiter waiter = (Waiter)cxt.getBean("waiter");
        waiter.greetTo("John");
	}

}

 후방 증강, 이상 던 지기 증강 과 서 라운드 증강 용법 의 차이 가 많 지 않 습 니 다. 단지 실현 되 는 인터페이스 가 다 를 뿐 입 니 다. 다음은 설명 하 겠 습 니 다. 저 는 테스트 코드 를 여러분 의 학습 에 업로드 하 겠 습 니 다. 다음은 우리 등급 의 증강, 즉 소개 강화 에 대해 이야기 하 겠 습 니 다. 우 리 는 이전 블 로그 대리 체제 의 사례 에 따라 소개 강 화 를 배 울 것 입 니 다. 우 리 는 앞에서 사용자 의 추 가 를 모니터링 하 는 데 사 용 됩 니 다.성능 을 추가 하고 삭제 합 니 다. 이 제 는 제어 가능 한 것 으로 바 꿉 니 다. 즉, 관리자 가 성능 모니터링 을 사용 하 는 지 여 부 를 제어 할 수 있 습 니 다.
우선 표지 대상 클래스 가 성능 모니터링 을 지원 하 는 지 여 부 를 정의 합 니 다.
package com.me.advice;

public interface Monitorable {
	/** 
	 * @param IsActive 
	 * true:        
	 * false:         
	 */
	public void setMonitorActive(boolean IsActive);
}

  Delegating Introduction Interceptor 를 계승 하여 목표 클래스 에 성능 모니터링 기능 을 도입 합 니 다. 코드 는 다음 과 같 습 니 다.
package com.me.util;

import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.support.DelegatingIntroductionInterceptor;

@SuppressWarnings("serial")
public class ControllablePerformanceMonitor extends
		DelegatingIntroductionInterceptor implements Monitorable {
	//          
	private ThreadLocal<Boolean> statusMap = new ThreadLocal<Boolean>();
	
	public void setMonitorActive(boolean IsActive) {
		statusMap.set(new Boolean(IsActive));		
	}
	
	public Object invoke(MethodInvocation mi)throws Throwable{
		Object obj = null;
		if(statusMap.get()!=null && statusMap.get().booleanValue()){
			PerformanceMonitor pm = new PerformanceMonitor();
			pm.start(mi.getClass().getName()+"."+mi.getMethod().getName());
			obj = super.invoke(mi);
			pm.end();
		}else{
			obj = super.invoke(mi);
		}
		return obj;
	}

}

 
프로필 소개 강화
<bean id="target" class="com.me.services.imp.UserServiceImp"/>
 	<bean id="pmonitor" class="com.me.util.ControllablePerformanceMonitor"/>
 	<!--      -->
 	<bean id="userService" class="org.springframework.aop.framework.ProxyFactoryBean">
 	<!--            -->
 	<property name="interfaces">
 		<value>com.me.util.Monitorable</value>
 	</property>
 	<property name="target" ref="target"/>
 	<property name="interceptorNames">
 		<idref local="pmonitor"/>
 	</property>
 	<!--               ,      CGLib       -->
 	<property name="proxyTargetClass" value="true"/>
 	</bean>

 테스트 소개 강화
package com.me.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.me.services.UserService;
import com.me.entity.*;
import com.me.util.Monitorable;
public class TestCotrollerPerformance {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		 ApplicationContext cxt = new ClassPathXmlApplicationContext("applicationContext.xml");
		 UserService service = (UserService)cxt.getBean("userService");
		 service.deleteUser(1);
		 service.insertUser(new User());
		 //      ,          Monitorable  
		 Monitorable monitor = (Monitorable)service;
		 monitor.setMonitorActive(true);
		 
		 service.deleteUser(1);
		 service.insertUser(new User());
	}

}

 
 
 
 

좋은 웹페이지 즐겨찾기