Spring 의 IOC 와 AOP (정적 에이전트, jdk 의 동적 에이전트, CGLIB 에이전트)
Spring 프레임 워 크 의 정 수 는 바로 그의 IOC 와 AOP 입 니 다. 면접 에서 도 자주 물 어보 기 때문에 여기 서 정리 하 겠 습 니 다.
IOC (Inversion of Control 반전 제어)
우선 우 리 는 어떤 통 제 를 반전 시 키 고 어떻게 반전 시 키 는 지 명확 하 게 해 야 한다.
우리 가 Spring 을 사용 하지 않 을 때, 우 리 는 일반적으로 대상 을 만 드 는 것 은 자신 이 수 동 으로 new 하 나 를 만 들 고, 이 대상 의 클래스 의 구조 방법 을 사용 하여 초기 화 합 니 다.이렇게 모 르 는 사이 에 각 층 간 의 결합 성 을 강화 했다. 예 를 들 어 우 리 는 MySQL 을 우리 의 DAO 층 으로 사용 하고 공장 을 떠 나 서 우 리 는 업무 층 에 인삼 이 있 는 구조 방법 을 써 서 우리 의 DAO 층 대상 을 전달 한 다음 에 new 를 나 오 는 것 이 아 닙 니까?이것 은 우리 의 업무 층 과 지구 층 이 매우 강 한 결합 성 을 가지 고 있다 는 것 을 의미한다. 만약 에 당신 의 지구 층 이 Oracle 로 바 뀌 거나 SQL Sever 가 당신 의 지구 층 인지 아 닌 지 대량의 코드 를 수정 해 야 한다.그러면 우리 가 IOC 를 사용 할 때 스스로 new 대상 에 가지 않 아 도 된다. 즉, 우리 가 대상 을 통제 하 는 이 권력 을 Spring 의 Bean 공장 으로 반전 시 켜 우리 에 게 만들어 주 고 우리 가 직접 사용 하면 된다.
DI (의존성 주입 의존 주입)
사실 주입 과 제어 반전 에 의존 하 는 것 은 상부 상조 이다. 우 리 는 IOC 를 사용 하여 각 층 의 일부 대상 을 만 들 기 때문에 우 리 는 설정 방식 을 통 해 이 대상 들 의 일반 속성 과 관련 속성 을 주입 하 는 방식 으로 A 대상 에 게 전달 해 야 한다.즉, 우리 가 호출 자 를 호출 하 는 어떤 방법 을 사용 할 때 그들 사이 에 어떤 의존 관계 가 생 겼 지만 호출 자의 대상 은 Spring 의 IOC 를 통 해 생 성 되 었 으 므 로 반드시 그 를 대기 자 에 주입 해 야 한 다 는 것 이다.
AOP (절단면 을 위 한 프로 그래 밍)
어 려 운 단어 입 니 다. 예 를 들 어 우리 가 코드 를 써 서 갑 의 아버지 에 게 전달 하려 고 할 때 갑자기 변경 요 구 를 받 았 습 니 다. 어떤 방법 전에 인증 을 추가 하고 호출 한 후에 로그 기능 을 추가 해 야 합 니 다. 어떻게 해 야 합 니까? 머리 가 썩 었 습 니 다.소스 코드 변경?불가능 합 니 다. 어떤 방법 을 위해 다른 방법 으로 큰 실 수 를 할 수 있 습 니 다. 그러면 우 리 는 Spring 에서 AOP 를 절단면 으로 프로 그래 밍 하면 완벽 하 게 해결 할 수 있 습 니 다. 먼저 명 사 를 소개 합 니 다.
이 예 를 들 어 인증 은 BeforeAdvice 입 니 다. 로 그 를 추가 하 는 것 은 AfterAdvice 입 니 다. 어떤 방법 은 PointCut 입 니 다. 즉, 우 리 는 AOP 를 이용 하여 코드 를 수정 하지 않 은 상태 에서 당신 의 pointcut 에 Advice 를 짜 줄 수 있 습 니 다. 설정 은 다음 과 같 습 니 다.
//ref
// add PointCut
// checkSecurity beforeAdvice
AOP 의 에이전트 모드
먼저 프 록 시 모드 가 무엇 인지 말씀 드 리 겠 습 니 다. 즉, 특정한 방법 으로 이런 대상 을 만 들 때 진정한 대상 을 만 드 는 것 이 아니 라 이런 유형의 프 록 시 대상 을 만 드 는 것 입 니 다. 이것 이 AOP 를 실현 할 수 있 는 이유 입 니 다. 실제 많은 프레임 워 크 는 사용 하 는 프 록 시 모델 로 효율 을 높이 고 공간 을 절약 합 니 다.
정적 에이전트
정적 대 리 는 사실 매우 간단 하 다. 그 는 자신 이 종 류 를 써 서 목표 류 와 같은 인 터 페 이 스 를 실현 해 야 한다.이 클래스 에서 목표 대상 을 정의 해 야 하 며 IOC 를 통 해 이 루어 질 수 있다.그 다음 에 인터페이스 에 있 는 방법 을 실현 하고 재 작성 한다. 예 를 들 어 특정한 방법 을 먼저 집행 하고 목표 류 대상 을 집행 하 는 이 방법 이다.이렇게 하면 정적 프 록 시 대상 을 만 들 고 정적 프 록 시 클래스 의 방법 을 사용 하여 '짜 기' 를 실현 할 수 있 습 니 다.
public class UserManagerImplProxy implements UserManager {
private UserManager userManager;
public void addUser(String username, String password) {
checkSecurity();
this.userManager.addUser(username, password);
}
private void checkSecurity() {
System.out.println("----------checkSecurity()---------------");
}
}
//////////
UserManager userManager = (UserManager)factory.getBean("UserManagerImplProxy");
userManager.addUser("admin", "123");
jdk 동적 에이전트
Spring 의 진정한 프 록 시 모드 는 jdk 의 동적 프 록 시 를 사용 하 는 것 입 니 다.
우 리 는 하나의 종 류 를 써 야 한다. 그러나 당신 이 실현 한 것 은 목표 류 의 인터페이스 가 아니 라 Invocation Handler 라 는 것 이다.대상 클래스 를 가리 키 는 Object 형식의 변수 가 있 습 니 다.인터페이스 에 있 는 방법 을 실현 하고 코드 를 직접 올 립 니 다.
public class SecurityHandler implements InvocationHandler {
private Object targetObject; //
public Object newProxy(Object targetObject) {
this.targetObject = targetObject;
System.out.println("----------newProxy()---------------");
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(),
this);
//return , ,
( , , this )
this ;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
checkSecurity(); //
Object ret = null;
try {
ret = method.invoke(this.targetObject, args); //
}catch(Exception e) {
e.printStackTrace();
throw new java.lang.RuntimeException(e);
}
return ret;
}
private void checkSecurity() {
System.out.println("----------checkSecurity()---------------");
}
}
//////////////////// /////////////////
public class Client {
public static void main(String[] args) {
// InvocationHandler
SecurityHandler handler = new SecurityHandler();
// newProxy ,
UserManager userManager = (UserManager)handler
.newProxy(new UserManagerImpl());
// addUser();
// , , this.invoke , handler invoke
// " "
userManager.addUser("admin", "123");
userManager.deleteUser(1);
}
}
정적 에이전트 와 동적 에이전트 의 차이
우리 가 정적 대 리 를 사용 할 때 우 리 는 목표 류 의 유형 명, 방법 명 을 알 아야 한다. 그러나 많은 상황 에서 우 리 는 알 수 없다. 우 리 는 프로그램 운영 에서 만 알 수 있다. 이 럴 때 동적 대 리 를 사용 해 야 한다. 더욱 유연 해 야 한다. 그러나 우 리 는 우리 의 목표 류 가 특정한 인 터 페 이 스 를 실현 해 야 한 다 는 것 을 발견 했다. 만약 에 특정한 유형 이 인 터 페 이 스 를 실현 하지 못 한다 면?
CGLIB 에이전트
그의 원리 도 매우 간단 하 다. 그 는 당신 의 목표 류 의 하위 클래스 이 며, 당신 의 목표 류 의 모든 방법 을 다시 쓸 것 이다. Object 유형의 변수 target 은 당신 이 어떤 방법 을 호출 할 때, 하위 클래스 의 어떤 방법 을 호출 하여 부모 클래스 의 이 방법 을 호출 하려 고 한다.그 와 목표 류 가 계승 관계 이기 때문에 목표 류 는 final 유형의 방법 이 없 는 것 이 좋 습 니 다. 그렇지 않 으 면 실현 할 수 없습니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.