AOP 방면 프로 그래 밍
Spring 에서 제공 하 는 내 장 된 AOP 지원 은 동적 AOP 메커니즘 을 바탕 으로 이 루어 집 니 다.기술적 인 측면 에서 볼 때 이른바 동적 AOP,즉 동적 프 록 시 모드 를 통 해 대상 의 방법 호출 전후 에 해당 하 는 처리 코드 를 삽입 하 는 것 이다.반면 Spring AOP 의 동적 프 록 시 모드 는 자바 Dynamic Proxy(인터페이스 지향)와 CGLib(Class 지향)를 기반 으로 이 루어 진다.앞서 언급 했 듯 이 Spring Framework 의'사무 관리'서 비 스 는 사실상 AOP 메커니즘 을 통 해 이 루어 졌 다.우 리 는 여기 서'사무 관리'를 예 로 들 어 동태 AOP 의 실현 에 대해 연 구 를 하고 한편 으로 는 동태 AOP 의 실현 원 리 를 탐구 하 며 다른 한편 으로 는 Spring 중의 사무 관리 체제 에 대한 이 해 를 강화 할 수 있다.
다음은 Dynamic Proxy 의 예 입 니 다.
AOPHandler.java
package aop;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class AOPHandler implements InvocationHandler {
private static Log logger = LogFactory.getLog(AOPHandler.class);
private List interceptors = null;
private Object originalObject;
/**
*
* @param obj
* @return
*/
public Object bind(Object obj) {
this.originalObject = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj
.getClass().getInterfaces(), this);
}
/**
* Invoke , Interceptor,
* (before)、 (after) (exceptionThrow)
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = null;
Throwable ex = null;
InvocationInfo invInfo = new InvocationInfo(proxy, method, args,
result, ex);
logger.debug("Invoking Before Intercetpors!");
System.out.println("Invoking Before Intercetpors!");
invokeInterceptorsBefore(invInfo);
try {
logger.debug("Invoking Proxy Method!");
System.out.println("Invoking Proxy Method!");
result = method.invoke(originalObject, args);
invInfo.setResult(result);
logger.debug("Invoking After Method!");
System.out.println("Invoking After Method!");
invokeInterceptorsAfter(invInfo);
} catch (Throwable tr) {
invInfo.setException(tr);
logger.debug("Invoking exceptionThrow Method!");
System.out.println("Invoking exceptionThrow Method!");
invokeInterceptorsExceptionThrow(invInfo);
throw new AOPRuntimeException(tr);
}
return result;
}
/**
* Interceptor
* @return
*/
private synchronized List getIntercetors() {
if (null == interceptors) {
interceptors = new ArrayList();
//Todo: , Interceptor
interceptors.add(new MyInterceptor());
}
return interceptors;
}
/**
*
* @param invInfo
*/
private void invokeInterceptorsBefore(InvocationInfo invInfo) {
List interceptors = getIntercetors();
int len = interceptors.size();
for (int i = 0; i < len; i++) {
((Interceptor) interceptors.get(i)).before(invInfo);
}
}
/**
*
* @param invInfo
*/
private void invokeInterceptorsAfter(InvocationInfo invInfo) {
List interceptors = getIntercetors();
int len = interceptors.size();
for (int i = len - 1; i >= 0; i--) {
((Interceptor) interceptors.get(i)).after(invInfo);
}
}
/**
*
* @param invInfo
*/
private void invokeInterceptorsExceptionThrow(InvocationInfo
invInfo) {
List interceptors = getIntercetors();
int len = interceptors.size();
for (int i = len - 1; i >= 0; i--) {
((Interceptor)
interceptors.get(i)).exceptionThrow(invInfo);
}
}
}
AOP Runtime Exception.java 이상 처리
package aop;
public class AOPRuntimeException extends RuntimeException {
AOPRuntimeException(Throwable e)
{
}
}
Interceptor.java 차단기 인터페이스
package aop;
public interface Interceptor {
public void before(InvocationInfo invInfo);
public void after(InvocationInfo invInfo);
public void exceptionThrow(InvocationInfo invInfo);
}
MyInterceptor.java 차단기 의 실현:
package aop;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class MyInterceptor implements Interceptor{
private static Log logger = LogFactory.getLog(MyInterceptor.class);
public void before(InvocationInfo invInfo) {
logger.debug("Pre-processing");
System.out.println("Pre-processing");
System.out.println("beginTransaction");
}
public void after(InvocationInfo invInfo) {
logger.debug("Post-processing");
System.out.println("Post-processing");
System.out.println("endTransaction");
}
public void exceptionThrow(InvocationInfo invInfo) {
logger.debug("Exception-processing");
System.out.println("Exception-processing");
System.out.println("rollback();");
}
}
AOFactory.java 생 성 에이전트 공장
package aop;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class AOPFactory {
private static Log logger = LogFactory.getLog(AOPFactory.class);
/**
*
* @param clzName
* @return
* @throws ClassNotFoundException
*/
public static Object getClassInstance(String clzName){
Class cls;
try {
cls = Class.forName(clzName);
return (Object)cls.newInstance();
} catch (ClassNotFoundException e) {
logger.debug(e);
throw new AOPRuntimeException(e);
} catch (InstantiationException e) {
logger.debug(e);
throw new AOPRuntimeException(e);
} catch (IllegalAccessException e) {
logger.debug(e);
throw new AOPRuntimeException(e);
}
}
/**
* , AOP
* @param clzName
* @return
*/
public static Object getAOPProxyedObject(String clzName){
AOPHandler txHandler = new AOPHandler();
Object obj = getClassInstance(clzName);
return txHandler.bind(obj);
}
}
InvocationInfo.java
package aop;
import java.lang.reflect.Method;
public class InvocationInfo {
Object proxy;
Method method;
Object[] args;
Object result;
Throwable Exception;
public InvocationInfo(Object proxy, Method method, Object[] args,
Object result, Throwable exception) {
super();
this.proxy = proxy;
this.method = method;
this.args = args;
this.result = result;
Exception = exception;
}
public Object getResult() {
return result;
}
public void setResult(Object result) {
this.result = result;
}
public Object[] getArgs() {
return args;
}
public void setArgs(Object[] args) {
this.args = args;
}
public Throwable getException() {
return Exception;
}
public void setException(Throwable exception) {
Exception = exception;
}
public Method getMethod() {
return method;
}
public void setMethod(Method method) {
this.method = method;
}
public Object getProxy() {
return proxy;
}
public void setProxy(Object proxy) {
this.proxy = proxy;
}
}
UserDAO.java
에이전트 가 필요 한 인터페이스
package aop;
public interface UserDAO {
public void saveUser();
}
UserDAOImp.java
package aop;
public class UserDAOImp implements UserDAO {
public void saveUser() {
// TODO Auto-generated method stub
System.out.println("UserDAOImp saveUser");
}
}
TestAOP.자바 테스트 클래스
package aop;
public class TestAOP {
public static void main(String[] args){
Object ob = AOPFactory.getAOPProxyedObject("aop.UserDAOImp");
UserDAO dao = (UserDAO)ob;
dao.saveUser();
}
}
실행 결과:
Invoking Before Intercetpors!
Pre-processing
beginTransaction
Invoking Proxy Method!
UserDAOImp saveUser
Invoking After Method!
Post-processing
endTransaction
프 록 시 효과 CGLib 와 Spring AOP 표시
Spring 에 서 는 CGLib 를 인터페이스 없 는 동적 에이전트 로 도입 했다.CGLib 는 Dynamic Proxy 의 프 록 시 메커니즘 과 기본적으로 유사 하지만 동적 으로 생 성 된 프 록 시 대상 은 특정한 인터페이스의 실현 이 아니 라 목표 클래스 에 대한 확장 하위 클래스 입 니 다.다시 말 하면 Dynamic Proxy 가 되 돌아 오 는 동적 프 록 시 클래스 는 목표 클래스 가 실현 하 는 인터페이스의 또 다른 실현 버 전 으로 목표 클래스 에 대한 프 록 시(예 를 들 어 UserDAOProxy 와 UserDAOImp 의 관계)를 실현 했다.CGLib 가 되 돌아 오 는 동적 프 록 시 클래스 는 대상 프 록 시 클래스 의 하위 클래스(프 록 시 클래스 가 UserDAOImp 클래스 로 확장 되 었 습 니 다)입 니 다.
CGLIB.프로젝트 를 참조 하려 면 몇 개의 jar 패 키 지 를 가 져 와 야 합 니 다:antlr-2.7.2.jar,asm-attrs.jar,aspectj-1.6.1.jar,aspectjrt.jar,aspectjweaver.jar
AOPInstrumenter.java
package aop;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class AOPInstrumenter implements MethodInterceptor{
private static Log logger =
LogFactory.getLog(AOPInstrumenter.class);
private Enhancer enhancer = new Enhancer();
public Object getInstrumentedClass(Class clz) {
enhancer.setSuperclass(clz);
enhancer.setCallback(this);
return enhancer.create();
}
public Object intercept(
Object o,
Method method,
Object[] methodParameters,
MethodProxy methodProxy)
throws Throwable {
logger.debug("Before Method =>"+method.getName());
System.out.println("Before Method =>"+method.getName());
Object result = methodProxy.invokeSuper(o, methodParameters);
logger.debug("After Method =>"+method.getName());
System.out.println("After Method =>"+method.getName());
return result;
}
}
UserDAOImp.java
package aop;
public class UserDAOImp {
public void saveUser()
{
System.out.println("UserDAOImp method saveUser");
}
}
TestAOPCGLib.java
package aop;
public class TestAOPCGLib {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
AOPInstrumenter aopInst = new AOPInstrumenter();
UserDAOImp userDAO =
(UserDAOImp) aopInst.getInstrumentedClass(UserDAOImp.class);
userDAO.saveUser();
}
}
TestAOPCLib 의 실행 결 과 는:
Before Method =>saveUser
UserDAOImp method saveUser
After Method =>saveUser
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.