에이전트 모드 - 정적 에이전트 에서 동적 에이전트 로 의 진화 과정
27663 단어 디자인 모드
프 록 시 모드 전송 도 어
다음은 정적 에이전트 에서 동적 에이전트 로 한 걸음 한 걸음 진화 한다.
먼저 정적 에이전트 의 인 스 턴 스 를 작성 합 니 다:
우선 subject (추상 적 인 주제 역할): IUserService
package com.soft.day1103.dao;
import com.soft.test.model.User;
import java.util.List;
public interface IUserService {
List findAllUser();
User findUserById(String id);
int add(User user);
}
realSubject 실제 테마 캐릭터 UserServiceImpl
package com.soft.day1103.dao.impl;
import com.soft.day1103.dao.IUserService;
import com.soft.test.model.User;
import java.util.ArrayList;
import java.util.List;
public class UserServiceImpl implements IUserService {
@Override
public List findAllUser() {
System.out.println(" ");
return new ArrayList();
}
@Override
public User findUserById(String id) {
System.out.println(" id" + id + " ");
return new User();
}
@Override
public int add(User user) {
System.out.println(" ");
return 0;
}
}
proxy 에이전트 테마 역할 UserServiceStaticProxy package com.soft.day1103.proxy;
import com.soft.day1103.dao.IUserService;
import com.soft.day1103.dao.impl.UserServiceImpl;
import com.soft.test.model.User;
import java.util.List;
public class UserServiceStaticProxy implements IUserService {
//
private UserServiceImpl userService = new UserServiceImpl();
/* start*/
/**
*
* @param methodName
*/
private void pre(String methodName){
System.out.println(methodName + " ");
}
/**
*
* @param methodName
*/
private void after(String methodName){
System.out.println(methodName + " ");
}
/* end*/
@Override
public List findAllUser() {
pre("findAllUser");
List list = userService.findAllUser();
after("findAllUser");
return list;
}
@Override
public User findUserById(String id) {
pre("findUserById");
User user = userService.findUserById(id);
after("findUserById");
return user;
}
@Override
public int add(User user) {
pre("add");
int addRes = userService.add(user);
after("add");
return addRes;
}
}
실체 클래스: (테스트 용 무의미)
package com.soft.day1103.model;
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
테스트 에이전트 클래스
package com.soft.day1103.proxy;
import com.soft.day1103.dao.IUserService;
import com.soft.test.model.User;
import org.junit.Test;
public class UserServiceStaticProxyTest {
private IUserService userService = new UserServiceStaticProxy();
@Test
public void findAllUser() throws Exception {
userService.findAllUser();
print();
}
@Test
public void findUserById() throws Exception {
userService.findUserById("111");
print();
}
@Test
public void add() throws Exception {
userService.add(new User());
print();
}
private void print(){
System.out.println("=====================================");
}
}
테스트 결과:
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
그 결과 실제 대상 이 되 는 방법 을 실행 할 때마다 프 록 시 논 리 를 삽입 하 는 것 은 프 록 시 성공 을 설명 하 는 것 으로 나 타 났 다.그러나 정적 에이전트 에 단점 이 있 습 니 다.
모든 실제 주제 캐릭터 는 반드시 하나의 대리 류 가 있어 야 한다.즉, 주제 캐릭터 가 하나 더 있 으 면 대리 류 가 하나 더 있어 야 한 다 는 것 이다.류 의 팽창 을 야기 할 수 있다.
지금 customer ServiceImpl 은 대리 가 필요 합 니 다. 이 럴 때 대리 류 를 만들어 야 합 니 다.
package com.soft.day1103.proxy;
import com.soft.day1103.dao.ICustomerService;
import com.soft.day1103.dao.impl.CustomerServiceImpl;
import com.soft.day1103.model.Customer;
import java.util.List;
public class CustomerServiceStaticProxy implements ICustomerService {
//
private ICustomerService userService = new CustomerServiceImpl();
/* start*/
/**
*
*
* @param methodName
*/
private void pre(String methodName) {
System.out.println(methodName + " ");
}
/**
*
*
* @param methodName
*/
private void after(String methodName) {
System.out.println(methodName + " ");
}
/* end*/
@Override
public List findAllCustomer() {
pre("findAllUser");
List list = userService.findAllCustomer();
after("findAllUser");
return list;
}
@Override
public Customer findUserById(String id) {
pre("findUserById");
Customer user = userService.findUserById(id);
after("findUserById");
return user;
}
@Override
public int add(Customer user) {
pre("add");
int addRes = userService.add(user);
after("add");
return addRes;
}
}
두 개의 정적 대리 류 를 관찰 한 결과 최적화 항목 을 발견 할 수 있다. 모든 방법 이 실행 전후의 코드 가 중복 되 고 공공 부분 으로 추출 할 수 있 지만 집행 방법 이 다 르 기 때문에 이 럴 때 반사 로 방법 을 집행 한 다음 에 반사 집행 방법 전에 대리 논리 처 리 를 할 수 있다.최 적 화 된 코드 를 통 해:이렇게 최적화 한 후에 테스트 를 한다.package com.soft.day1103.proxy; import com.soft.day1103.dao.IUserService; import com.soft.day1103.dao.impl.UserServiceImpl; import com.soft.test.model.User; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.List; public class UserServiceStaticProxy implements IUserService { // private UserServiceImpl userService = new UserServiceImpl(); /* start*/ /** * * @param methodName */ private void pre(String methodName){ System.out.println(methodName + " "); } /** * * @param methodName */ private void after(String methodName){ System.out.println(methodName + " "); } /* end*/ @Override public List
findAllUser() { return (List)excute("findAllUser",new Object[]{},null); } @Override public User findUserById(String id) { return (User)excute("findUserById",new Object[]{id},String.class); } @Override public int add(User user) { return (int)excute("add",new Object[]{user},User.class); } private Object excute(String methodName, Object[] param, Class... params){ Object obj = null; try { Method method = userService.getClass().getMethod(methodName, params); pre(methodName); obj = method.invoke(userService,param); after(methodName); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return obj; } } add add ===================================== findAllUser findAllUser ===================================== findUserById id111 findUserById =====================================
CustomerServiceStaticProxy 。
package com.soft.day1103.proxy; import com.soft.day1103.dao.IUserService; import com.soft.day1103.dao.impl.UserServiceImpl; import com.soft.test.model.User; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.List; public class UserServiceStaticProxy implements IUserService { // private UserServiceImpl userService = new UserServiceImpl(); /* start*/ /** * * @param methodName */ private void pre(String methodName){ System.out.println(methodName + " "); } /** * * @param methodName */ private void after(String methodName){ System.out.println(methodName + " "); } /* end*/ @Override public List
findAllUser() { return (List)excute("findAllUser",new Object[]{},null); } @Override public User findUserById(String id) { return (User)excute("findUserById",new Object[]{id},String.class); } @Override public int add(User user) { return (int)excute("add",new Object[]{user},User.class); } private Object excute(String methodName, Object[] param, Class... params){ Object obj = null; try { Method method = userService.getClass().getMethod(methodName, params); pre(methodName); obj = method.invoke(userService,param); after(methodName); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return obj; } } 对比两个静态代理类,还是有可以提取出来的部分,excute方法可以再次做拆分处理,放到一个共通处理类里面去。
package com.soft.day1103.proxy; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class InvokeHandler { /** * */ private Object obj; public InvokeHandler(Object obj) { this.obj = obj; } /* start*/ /** * * @param methodName */ private void pre(String methodName){ System.out.println(methodName + " "); } /** * * @param methodName */ private void after(String methodName){ System.out.println(methodName + " "); } /* end*/ public Object excute(String methodName, Object[] param, Class... params){ try { Method method = obj.getClass().getMethod(methodName, params); pre(methodName); obj = method.invoke(obj,param); after(methodName); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return obj; } }
然后两个静态代理类,的变化比较大훨씬 상쾌 해 지 는 지 보고 대리 논 리 를 따로 포장 하고 대리 류 는 대리 논 리 를 호출 합 니 다.package com.soft.day1103.proxy; import com.soft.day1103.dao.IUserService; import com.soft.day1103.dao.impl.UserServiceImpl; import com.soft.test.model.User; import java.util.List; public class UserServiceStaticProxy implements IUserService { // private UserServiceImpl userService = new UserServiceImpl(); private InvokeHandler handler = new InvokeHandler(userService); @Override public List
findAllUser() { return (List) handler.excute("findAllUser", new Object[]{}, null); } @Override public User findUserById(String id) { return (User) handler.excute("findUserById", new Object[]{id}, String.class); } @Override public int add(User user) { return (int) handler.excute("add", new Object[]{user}, User.class); } } , 。 , , 。
InvokeHandler, (InvokeHandler) 。
jdk InvocationHandler
InvokeHandlerpackage com.soft.day1103.proxy; import java.lang.reflect.Method; public interface InvocationHandler { public Object invoke(Method method, Object[] param); }
UserServiceStaticProxypackage com.soft.day1103.proxy; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class InvokeHandler implements InvocationHandler{ /** * */ private Object obj; public InvokeHandler(Object obj) { this.obj = obj; } /* start*/ /** * * @param methodName */ private void pre(String methodName){ System.out.println(methodName + " "); } /** * * @param methodName */ private void after(String methodName){ System.out.println(methodName + " "); } /* end*/ @Override public Object invoke(Method method, Object[] param) { Object object = null; try { pre(method.getName()); object = method.invoke(obj,param); after(method.getName()); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return object; } }
UserServiceStatic Proxy 코드 도 약간 조정 되 었 습 니 다. 이것 은 jdk 동적 에이전트 의 매개 변수 등 과 일치 하기 위해 조정 한 것 이지 만 사상 은 같 습 니 다.package com.soft.day1103.proxy; import com.soft.day1103.dao.IUserService; import com.soft.test.model.User; import java.lang.reflect.Method; import java.util.List; public class UserServiceStaticProxy implements IUserService { // private InvocationHandler handler; public UserServiceStaticProxy(InvocationHandler handler) { this.handler = handler; } @Override public List
findAllUser() { return (List) excute("findAllUser", new Object[]{}, null); } @Override public User findUserById(String id) { return (User) excute("findUserById", new Object[]{id}, String.class); } @Override public int add(User user) { return (int) excute("add", new Object[]{user}, User.class); } private Object excute(String methodName, Object[] param, Class... params) { Object obj = null; try { Method method = IUserService.class.getMethod(methodName, params); obj = handler.invoke(method, param); } catch (NoSuchMethodException e) { e.printStackTrace(); } return obj; } } 。
우선 에이전트 가 필요 한 클래스 를 실례 화하 고 에이전트 가 필요 한 클래스 를 에이전트 논리 클래스 Invocation Handler 에 넣 고,package com.soft.day1103.proxy; import com.soft.day1103.dao.IUserService; import com.soft.day1103.dao.impl.UserServiceImpl; import com.soft.test.model.User; import org.junit.Test; public class UserServiceStaticProxyTest { // , 。 private IUserService userServicesss = new UserServiceImpl(); InvocationHandler handler = new InvokeHandler(userServicesss); private IUserService userService = new UserServiceStaticProxy(handler); @Test public void findAllUser() throws Exception { userService.findAllUser(); print(); } @Test public void findUserById() throws Exception { userService.findUserById("111"); print(); } @Test public void add() throws Exception { userService.add(new User()); print(); } private void print(){ System.out.println("====================================="); } }
InvocationHandler 。
:
add add ===================================== findAllUser findAllUser ===================================== findUserById id111 findUserById ===================================== 。
, , ?
, , 。
。
:
Proxy
클래스 생 성기 ClassMakerpackage com.soft.day1103.proxy; import com.soft.day1103.util.ClassMaker; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class Proxy { public static Object newProxyInstance(Class cla, InvocationHandler handler){ Class createClass = ClassMaker.createProxyClass(cla); try { Constructor constructor = createClass.getConstructor(InvocationHandler.class); return constructor.newInstance(handler); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return null; } }
현재 동적 에이전트 테스트 를 진행 하고 있 습 니 다.대 리 를 동적 으로 실현 할 수 있 는 지 확인 하 다.package com.soft.day1103.util; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.Method; public class ClassMaker { private static final String IMPORT = "import "; private static final String FENHAO = ";
"; private static final String CLASS_PUBLIC = "public class "; private static final String IMPLEMANT = " implements "; private static final String QIANKUOHAO = "{"; private static final String HOUKUOHAO = "}"; private static final String PRIVATE_ = "private "; private static final String PUBLIC = "public "; private static final String NEWLINE = "
"; public static Class classLoad(String classInfo, String className) { try { FileOutputStream fo = new FileOutputStream("D:\\myproject\\mybatisLearn\\src\\main\\java\\com\\soft\\day1103\\proxy\\" + className + ".java"); fo.write(classInfo.getBytes()); fo.flush(); Thread.sleep(1000); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } Class retu = null; try { retu = Class.forName("com.soft.day1103.proxy." + className); } catch (ClassNotFoundException e) { e.printStackTrace(); } return retu; } public static Class createProxyClass(Class targetObject) { StringBuffer sb = new StringBuffer(); sb.append("package com.soft.day1103.proxy;"); sb.append("import java.lang.reflect.Method;"); String interfaceName = targetObject.getSimpleName(); sb.append("import " + targetObject.getPackage().getName() +"."+ interfaceName + ";"); Method[] methods = targetObject.getMethods(); for (Method method : methods) { Class returnType = method.getReturnType(); if(needImport(returnType)){ sb.append("import " + returnType.getPackage().getName() +"."+ returnType.getSimpleName() + ";"); } } // sb.append(" public class " + interfaceName + "Proxy implements " + interfaceName + " {"); // sb.append("private InvocationHandler handler;"); // sb.append("public " + interfaceName + "Proxy(InvocationHandler handler) {"); sb.append("this.handler = handler;}"); // for (Method method : methods) { Class returnType = method.getReturnType(); Class[] methodParamClass = method.getParameterTypes(); sb.append("@Override" + NEWLINE); sb.append(PUBLIC + returnType.getName() + " " + method.getName() + "("); // StringBuffer refMethodParamters = new StringBuffer(); int index = 0; // StringBuffer methodParams = new StringBuffer(); // class StringBuffer refMethodClasses = new StringBuffer(); for (Class methodParam : methodParamClass) { String paramName = methodParam.getName(); methodParams.append(paramName + " param" + index + ","); refMethodParamters.append(" param" + index + ","); String[] arr = paramName.split("\\."); refMethodClasses.append(arr[arr.length - 1] + ".class" + ","); index++; } if (methodParams.length() > 0) { sb.append(methodParams.substring(0, methodParams.toString().length() - 1)); } sb.append(")" + QIANKUOHAO + NEWLINE); if (refMethodParamters.length() > 0) { sb.append("Object[] objects = { " + refMethodParamters.substring(0, refMethodParamters.length() - 1) + "}" + FENHAO + NEWLINE); } else { sb.append("Object[] objects = new Object[" + methodParamClass.length + "]" + FENHAO + NEWLINE); } if (needReturn(returnType)) { sb.append("return (" + returnType.getName() + ")"); } String classes = null; if(refMethodClasses.length() > 0){ classes = refMethodClasses.substring(0,refMethodClasses.length()-1); } sb.append("excute(\"" + method.getName() + "\" , objects , " + classes + ")" + FENHAO + NEWLINE); sb.append(HOUKUOHAO + NEWLINE); } // sb.append(" private Object excute(String methodName, Object[] param, Class... params) {"); sb.append("Object obj = null;"); sb.append("try {"); sb.append("Method method = " + interfaceName + ".class.getMethod(methodName, params);"); sb.append("obj = handler.invoke(method, param);"); sb.append("} catch (NoSuchMethodException e) {"); sb.append(" e.printStackTrace();}"); sb.append("return obj;}"); sb.append(HOUKUOHAO + FENHAO + NEWLINE); return classLoad(sb.toString(), interfaceName + "Proxy"); } private static boolean needImport(Class tar) { return "voidStringintdoublelangfloatbooleanbytecharshort".indexOf(tar.getSimpleName()) == -1; } private static boolean needReturn(Class tar) { return "void".indexOf(tar.getSimpleName()) == -1; } }:
, java 。 , java 。 。 :
IUserService
테스트 결과:@Test public void testproxy() throws Exception { IUserService iUserService = (IUserService)Proxy.newProxyInstance(IUserService.class, handler); iUserService.add(new User()); print(); }
add add =====================================
ICustomerService
테스트 결과:@Test public void testproxy() throws Exception { ICustomerService iUserService = (ICustomerService)Proxy.newProxyInstance(ICustomerService.class, handler); iUserService.add(new Customer()); print(); }
add add =====================================
。 。 :
package com.soft.day1103.proxy; import java.lang.reflect.Method; import com.soft.day1103.dao.IUserService; import java.util.List; import com.soft.test.model.User; public class IUserServiceProxy implements IUserService { private InvocationHandler handler; public IUserServiceProxy(InvocationHandler handler) { this.handler = handler; } @Override public int add(com.soft.test.model.User param0) { Object[] objects = {param0}; return (int) excute("add", objects, User.class); } @Override public java.util.List findAllUser() { Object[] objects = new Object[0]; return (java.util.List) excute("findAllUser", objects, null); } @Override public com.soft.test.model.User findUserById(java.lang.String param0) { Object[] objects = {param0}; return (com.soft.test.model.User) excute("findUserById", objects, String.class); } private Object excute(String methodName, Object[] param, Class... params) { Object obj = null; try { Method method = IUserService.class.getMethod(methodName, params); obj = handler.invoke(method, param); } catch (NoSuchMethodException e) { e.printStackTrace(); } return obj; } };
package com.soft.day1103.proxy; import com.soft.day1103.dao.ICustomerService; import com.soft.day1103.model.Customer; import java.lang.reflect.Method; public class ICustomerServiceProxy implements ICustomerService { private InvocationHandler handler; public ICustomerServiceProxy(InvocationHandler handler) { this.handler = handler; } @Override public int add(com.soft.day1103.model.Customer param0) { Object[] objects = {param0}; return (int) excute("add", objects, Customer.class); } @Override public java.util.List findAllCustomer() { Object[] objects = new Object[0]; return (java.util.List) excute("findAllCustomer", objects, null); } @Override public com.soft.day1103.model.Customer findUserById(java.lang.String param0) { Object[] objects = {param0}; return (com.soft.day1103.model.Customer) excute("findUserById", objects, String.class); } private Object excute(String methodName, Object[] param, Class... params) { Object obj = null; try { Method method = ICustomerService.class.getMethod(methodName, params); obj = handler.invoke(method, param); } catch (NoSuchMethodException e) { e.printStackTrace(); } return obj; } };
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
디자인 모델 의 공장 모델, 단일 모델자바 는 23 가지 디자인 모델 (프로 그래 밍 사상/프로 그래 밍 방식) 이 있 습 니 다. 공장 모드 하나의 공장 류 를 만들어 같은 인 터 페 이 스 를 실현 한 일부 종 류 를 인 스 턴 스 로 만 드 는 것...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.