자바 AOP 원리 및 실례 용법 총결산
절단면 프로 그래 밍
프로 그래 밍 에서 우 리 는 높 은 결합 과 낮은 내부 집적 을 만족 시 켜 야 하기 때문에 프로 그래 밍 은 6 대 원칙,하나의 법칙 을 만족 시 켜 야 한다.
AOP 가 절단면 을 대상 으로 프로 그래 밍 하 는 것 은 바로 이러한 원칙 을 만족 시 키 기 위 한 프로 그래 밍 사상 이다.
1.장식 자 모드:
우리 가 대상 에 게 기능 을 추가 해 야 할 때 단일 한 직책 원칙 을 만족 시 키 기 위해 장식 자 모델 로 프로 그래 밍 을 하고 원래 의 종 류 를 장식 할 수 있 는 종 류 를 만 들 수 있다.이런 종 류 는 원래 의 기능 에 추가 해 야 하 는 기능 이다.
예 를 들 어 한 가지 유형 안에 도 서 를 추가 하 는 기능 이 있다.
@Service
public class BookSericeImpl implements BookSerice {
@Override
public void addOne(BokBean bokBean) {
System.out.println(" : ");
}
@Override
public void deletOne(Long bookId) {
System.out.println(" : ");
}
}
이 를 바탕 으로 인쇄 로 그 를 추가 하 는 기능 이 필요 합 니 다.
public class BooklogServiceImpl implements BookSerice {
private BookSerice bookSerice;
public BooklogServiceImpl(BookSerice bookSerice) {
this.bookSerice = bookSerice;
}
@Override
public void addOne(BokBean bokBean) {
System.out.println(" ");
this.bookSerice.addOne(bokBean);
System.out.println(" ");
}
@Override
public void deletOne(Long bookId) {
System.out.println(" ");
this.bookSerice.deletOne(323L);
System.out.println(" ");
}
}
다음은 이 증강 후의 대상 을 호출 하 겠 습 니 다.
public void test1(){
//Aop :
//
BookSerice bookSerice = new BookSericeImpl();
// ,
// .
bookSerice = new BooklogServiceImpl(bookSerice);
// ,
bookSerice.addOne(new BokBean());
}
이렇게 해서 우 리 는 원래 코드 를 바 꾸 지 않 는 토대 에서 기능 을 추 가 했 고 단일 직책 의 원칙 을 만족 시 켜 코드 의 결합 성 을 낮 추 었 다.그러나 인터페이스 에 여러 가지 방법 이 있다 면 모든 방법 이 로그 기능 을 추가 해 야 한다 면 중복 코드 가 많이 나타 나 고 장식 자 모드 는 여러 개의 관계 가 없 는 클래스 를 동시에 강화 할 수 없다.
그래서 자바 는 동적 에이전트 기술 을 도입 하여 기능 을 증가 시 켰 다.
동적 에이전트
자바 에서 동적 대 리 는 두 가지 실현 방식 이 있 습 니 다.
① 인터페이스 가 있 는 클래스 의 대 리 를 대상 으로 jdk 에서 가방 을 반사 하 는 동적 대 리 를 사용 합 니 다.
② 인터페이스 가 없 는 클래스 의 프 록 시 에 대해 제3자 jar 패키지 Enhancer 를 사용 합 니 다.
인터페이스 도 없고 final 도 없다 면 강화 할 수 없다.
1.첫 번 째 실현:
인터페이스 기반 동적 에이전트,자바 내부 반사 팩 사용 강화
이런 방식 으로 대상 을 만 드 는 것 은 목표 대상 의 형제 대상 이다.
마찬가지 로 위 는 인터페이스의 두 가지 기능 을 실현 한 유형 이다.
@Service
public class BookSericeImpl implements BookSerice {
@Override
public void addOne(BokBean bokBean) {
System.out.println(" : ");
}
@Override
public void deletOne(Long bookId) {
System.out.println(" : ");
}
}
대상 을 통 해 위의 두 가지 방법 을 호출 합 니 다.
public void test2(){
//
BookSerice bookSerice = new BookSericeImpl();
//
ClassLoader classLoader = bookSerice.getClass().getClassLoader();
//
Class<?>[] interfaces = bookSerice.getClass().getInterfaces();
// , ( , ,InvocationHandler )
bookSerice = (BookSerice) Proxy.newProxyInstance(classLoader, interfaces, new LogHandler(bookSerice));
bookSerice.addOne(new BokBean());
bookSerice.deletOne(232L);
}
프 록 시 대상 을 만 들 때 InvocationHandler 인터페이스 클래스 의 대상 이 필요 합 니 다.다음은 이러한 구현 클래스 를 만 듭 니 다.
public class LogHandler implements InvocationHandler {
//
//
private Object target;
public LogHandler(Object target) {
this.target = target;
}
// , invoke
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String classname = target.getClass().getName();
String methodName = method.getName();
System.out.println(classname+"."+methodName+" ");
// Method (addone)
Object value = method.invoke(target, args);
System.out.println(classname+"."+methodName+" ");
return value;
}
}
이렇게 동적 대 리 를 실현 한 후에 실현 되 는 인터페이스 에 몇 가지 방법 이 있 든 지 간 에 당신 은 이 방법 을 호출 하면 이 방법 을 강화 할 것 입 니 다.모든 방법 에 대해 증강 기능 을 한 번 쓰 지 않 아 도 됩 니 다.또한 이 증강 류 LogHandler 류 와 원래 의 실현 류 BookSericeImpl 류 는 결합 성 이 없습니다.이것 은 당신 이 어떤 인터페이스 류 의 실현 류 든 지 간 에 이러한 대상 을 대리 하면 이러한 방법 에 이 새로운 기능 을 추가 할 수 있다 는 것 입 니 다.
전체적으로 보면 이런 동적 대리 실현 방식 은 반사 기술 을 이용 하여 호출 된 방법 명 을 찾 아 이 방법 에 대해 강화 하 는 것 이다.
어떤 방법 에 기능 을 추가 할 필요 가 없 을 때 는 가지 고 있 지 않 아 도 된다.
2.두 번 째 실현:
클래스 기반 동적 에이전트,cglib 프레임 워 크 사용.
이 방식 으로 만 든 프 록 시 대상 은 대상 의 하위 클래스 대상 입 니 다.
두 번 째 방식 은 제3자 jar 패 키 지 를 이용 하여 CGLIB 패 키 지 를 다운로드 하 는 것 입 니 다.
jar 패키지 의 Enhancer 클래스 를 이용 하여 증강 대상 을 만 듭 니 다.
증강 대상 을 만 들 려 면 원래 대상 의 클래스 이름 에 따라 클래스 증강 기 를 만 들 고 원래 대상 의 유형 에 따라 하위 프 록 시 대상 을 만들어 야 합 니 다.
속성 은 증강 대상 set 방법 을 통 해 값 을 부여 합 니 다.이전 방식 은 호출 방법 Proxy.newProxy Instance 를 통 해 전 참 됩 니 다.
public void test3(){
//
BookSerice bookSerice = new BookSericeImpl();
Enhancer enhancer = new Enhancer();
//
enhancer.setClassLoader(bookSerice.getClass().getClassLoader());
// ,
enhancer.setSuperclass(bookSerice.getClass());
// , Callback , .
enhancer.setCallback(new TimeMethodInterceptor(bookSerice));
//
bookSerice = (BookSerice) enhancer.create();
bookSerice.addOne(new BokBean());
bookSerice.deletOne(1l);
}
Callback 인터페이스의 실현 클래스,즉 기능 강화 부분 을 만 듭 니 다.이 부분 은 첫 번 째 방식 의 실현 과 마찬가지 로 반 사 를 통 해 기능 을 추가 하 는 과정 에서 원래 의 방법 을 호출 하 는 것 이다.
//Callback ,
public class TimeMethodInterceptor implements MethodInterceptor {
private Object target;
public TimeMethodInterceptor(Object target) {
this.target = target;
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//
// 1970 1 1 0 0
long start = System.currentTimeMillis();
Object value = method.invoke(target, objects);
long time = System.currentTimeMillis() - start;
System.out.println(" "+time+" ");
return null;
}
}
요약:두 가지 방법의 차이:
첫 번 째 는 jdk 내부 방법 으로 프 록 시 대상 을 만 드 는 것 입 니 다.생 성 과정 에서 대상 의 인터페이스 가 필요 하기 때문에 인터페이스 류 가 있 는 대상 에 게 만 프 록 시 를 할 수 있 습 니 다.
두 번 째 는 제3자 jar 패키지 의 인 텐 시파 이 어(Enhancer)를 이용 하여 프 록 시 대상 을 만 들 고 set 방법 으로 필요 한 속성 값 을 부여 합 니 다.인터페이스 가 없 기 때문에 대상 의 하위 프 록 시 대상 을 만 듭 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 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에 따라 라이센스가 부여됩니다.