디자인 모드: 프 록 시 모드 (프 록 시 패턴)

에이전트 모드
프 록 시 모드 는 이 대상 에 대한 접근 을 제어 하기 위해 다른 대상 에 게 프 록 시 를 제공 합 니 다.어떤 경우 에 한 고객 이 다른 대상 을 직접 인용 하고 싶 지 않 거나 인용 할 수 없 으 며 대리 대상 은 클 라 이언 트 와 목표 대상 사이 에서 중개 역할 을 할 수 있다.
 
 
 
대리 모드 는 일반적으로 세 가지 역할 과 관련된다.
1 > 추상 적 인 역할: 실제 대상 과 대리 대상 의 공동 인 터 페 이 스 를 설명 합 니 다.
2 > 대리 역할: 대리 대상 역할 내부 에 실제 대상 에 대한 인용 이 포함 되 어 있어 실제 대상 을 조작 할 수 있 고 대리 대상 은 실제 대상 과 같은 인 터 페 이 스 를 제공 하여 언제든지 실제 대상 을 대체 할 수 있 도록 한다.또한 대리 대상 은 실제 대상 작업 을 수행 할 때 다른 조작 을 추가 할 수 있 으 며 실제 대상 에 대해 36826 줄 로 포장 하 는 것 과 같다.
3 > 실제 역할: 대리 역할 이 대표 하 는 진실 한 대상 은 우리 가 최종 적 으로 인용 해 야 할 대상 이다.
 
 
1. 우리 스스로 간단 한 대리 모델 을 만 듭 니 다.
1. 추상 적 인 캐릭터 새로 만 들 기: Subject 인터페이스 
 
package com.kaishengit.proxy;

public interface Subject {
	public void sales();//  
}

 
 2. 실제 캐릭터 새로 만 들 기: RealSubject (Subject 인터페이스 구현)
 
package com.kaishengit.proxy;
//Dell
public class RealSubject implements Subject{

	@Override
	public void sales() {
		System.out.println("Dell    ");
	}

}

 
 3. 새 프 록 시 역할: SubjectProxy (Subject 인터페이스 구현) 
 
package com.kaishengit.proxy;

//  
public class SubjectProxy implements Subject{
	
	private Subject subject;
	
	/**
	 *          
	 * @param subject
	 */
	public SubjectProxy(Subject subject){
		this.subject = subject;
	}
	@Override
	public void sales() {
		System.out.println("  ");//      ...
		subject.sales();
		System.out.println("   ");//      ...
	}

}

 
 4. 테스트 해 보 자.
 
package com.kaishengit.proxy;

public class Test {
	public static void main(String[] args) {
		//     
		RealSubject rs = new RealSubject();
		
		//  
		SubjectProxy sp = new SubjectProxy(rs);
		
		sp.sales();
	}
}

 
 실행 결과:
--------------------------------------
 
흔들거리다
Dell 판매 컴퓨터
물건 을 보내다
 
--------------------------------------
 
ok......
 
 
자바 동적 에이전트
자바 에서 동적 대 리 는 반드시 인터페이스 프로 그래 밍 을 해 야 합 니 다. 즉, 피 에이전트 대상 이 인 터 페 이 스 를 실현 해 야 합 니 다. 이것 은 자바 동적 에이전트 의 결함 입 니 다.자바 동적 프 록 시 는 Invocation Handler 인 터 페 이 스 를 빌 렸 다.
Spring 의 AOP 는 자바 동적 에이전트 에 사 용 됩 니 다.
 
1. 피 에이전트 대상 이 인 터 페 이 스 를 실현 해 야 하기 때문에 우 리 는 먼저 인터페이스 (Dao) 를 새로 만 듭 니 다.
 
package com.kaishengit.proxy.java;

public interface Dao {
	public void save();
}

 다음은 피 에이전트 대상 (인터페이스 구현) 을 만 듭 니 다: UserDao
 
package com.kaishengit.proxy.java;

public class UserDao implements Dao{

	@Override
	public void save() {
		System.out.println("save success!");
	}

}
 
2. 우 리 는 Invocation Handler 인 터 페 이 스 를 실현 하 는 클래스 를 만 듭 니 다: MyInvocation Handler
 
package com.kaishengit.proxy.java;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class MyInvocationHandler implements InvocationHandler{
	
	private Object obj;
	
	//        
	public MyInvocationHandler(Object obj){
		this.obj = obj;
	}
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("before");//      
		Object result = method.invoke(obj, args);//          
		System.out.println("after");//      
		return result;
	}

}

 3. 테스트 해 보 자.
 
 
package com.kaishengit.proxy.java;

import java.lang.reflect.Proxy;

public class Test {
	public static void main(String[] args) {
		UserDao ud = new UserDao();//     
		
		MyInvocationHandler mih = new MyInvocationHandler(ud);//       InvocationHandler    
		//    proxyDao
		Dao proxyDao = (Dao) Proxy.newProxyInstance(ud.getClass().getClassLoader(), ud.getClass().getInterfaces(), mih);
		
		proxyDao.save();
	}
}

 실행 결과:
------------------------------------------
 
before
save success!
after
------------------------------------------
 
3. CGLib 를 사용 하여 동적 대 리 를 진행 합 니 다.
cglib 의 jar 패 키 지 를 가 져 와 야 합 니 다. 원리: 프 록 시 대상 이 인 터 페 이 스 를 실현 하지 않 으 면 동적 으로 하나의 하위 클래스 를 만들어 프 록 시 모드 를 실현 합 니 다.그렇지 않 으 면 자바 동적 프 록 시 모드 를 사용 합 니 다.cglib 가방 의 MethodInterceptor 인 터 페 이 스 를 빌려 야 합 니 다.
Spring 에 서 는 cglib 의 jar 패 키 지 를 가 져 왔 습 니 다. 그 중의 AOP 는 프 록 시 모드 를 사용 하여 프 록 시 대상 이 인 터 페 이 스 를 실현 하지 못 했 을 때 대응 합 니 다.
 
1. 우 리 는 피 에이전트 대상 을 새로 만 들 었 습 니 다: UserDao (하하, 어떠한 인터페이스 도 실현 하지 못 했 군요)
 
package com.kaishengit.proxy.cglib;

public class UserDao {
	public void save(){
		System.out.println("save success!");
	}
}

2. 우 리 는 새로운 클래스 를 만 들 었 다. MethodInterceptor 인터페이스: DaoIntercept
 
 
package com.kaishengit.proxy.cglib;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class DaoIntercept implements MethodInterceptor{

	@Override
	public Object intercept(Object object, Method method, Object[] args,
			MethodProxy methodProxy) throws Throwable {
		System.out.println("before");//      ...
		//   methodProxy invokeSuper
		Object result = methodProxy.invokeSuper(object, args);
		System.out.println("after");//      ...
		return result;
	}

}

 3. 테스트 해 보 자.
 
package com.kaishengit.proxy.cglib;

import net.sf.cglib.proxy.Enhancer;

public class Test {
	public static void main(String[] args) {
		UserDao dao = new UserDao();
		
		//Enhancer   cglib   
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(dao.getClass());
		enhancer.setCallback(new DaoIntercept());
		
		//      
		UserDao proxyDao = (UserDao) enhancer.create();
		proxyDao.save();
	}
}

 실행 결과:
----------------------------------------------------
 
before
save success!
after
----------------------------------------------------
 
----end----

좋은 웹페이지 즐겨찾기