1. 에이전트 모드
프록시 모델은 영어로 프록시 또는 대리라고하며 둘 다 중국어로 "에이전트"로 번역 될 수 있습니다. 소위 대리는 한 사람이나 기관이 다른 사람이나 다른 기관을 대신하여 조치를 취한다는 것을 의미합니다. 경우에 따라 클라이언트는 객체를 원하거나 직접 참조 할 수 없으며 프록시 객체는 클라이언트와 대상 객체 사이의 중개자 역할을 할 수 있습니다.
거래의 실행 프로세스를 단순히 시뮬레이션하여 다양한 에이전트 간의 차이점을 설명하십시오.
1.1 정적 프록시
소스 코드는 프로그래머에 의해 생성되거나 특정 도구에 의해 자동으로 생성 된 다음 컴파일됩니다. 프로그램이 실행되기 전에 프록시 클래스의 .class 파일이 이미 존재합니다.
공개 인터페이스 persondao {void saveperson ();} 공개 클래스 persondaoimpl은 persondao {@override public void saveperson () {system.out.println ( "save person")을 구현합니다. }} 공개 클래스 트랜잭션 {void begintransaction () {System.out.println ( "트랜잭션 시작"); } void commit () {system.out.println ( "commit"); }}다음으로 정적 프록시 클래스를 작성하십시오 --- Persondao 인터페이스를 구현하십시오
/*** 정적 프록시 클래스* @Author qjc*/공개 클래스 PersondaoProxy Persondao {persondao persondao; 거래 거래; persondaoproxy (persondao persondao, 거래 거래) {this.persondao = persondao; this.transaction = 트랜잭션; } @override public void saveperson () {this.transaction.begintransaction (); this.persondao.saveperson (); this.transaction.commit (); }}시험
/*** 정적 프록시 테스트* @Author qjc*/public class testpersonproxy {@test public void testsave () {persondao persondao = 새로운 persondaoimpl (); 트랜잭션 트랜잭션 = 새로운 트랜잭션 (); persondaoproxy proxy = 새로운 persondaoproxy (persondao, 거래); proxy.saveperson (); }}요약 :
1. 정적 프록시 모드는 트랜잭션을 재사용하지 않습니다
2. 100 개의 클래스와 100 개의 프록시가 있다고 가정하십시오. 인터페이스에 몇 개의 메소드가 있는지, 프록시 계층에서 구현 해야하는 메소드 수 및 많은 방법을 열고 많은 방법을 제출해야합니다.
3. 프록시가 여러 인터페이스를 구현하면 인터페이스 중 하나가 변경되면 (메소드가 추가됨) 프록시도 그에 따라 변경해야합니다.
1.2 JDK 동적 프록시
동적 프록시 클래스 : 프로그램이 실행될 때 반사 메커니즘을 사용하여 동적으로 생성됩니다.
JDK의 동적 프록시는 네 가지 조건을 충족해야합니다. 1. 대상 인터페이스 2. 대상 클래스 3. 인터셉터 4. 프록시 클래스
Persondao 인터페이스 사용, persondaoimpl 클래스 및 트랜잭션 클래스 사용 이전 예제
인터셉터를 작성하십시오
import java.lang.reflect.invocationHandler; import java.lang.reflect.method;/** * interceptor * 1. * 2에서 대상 클래스 가져 오기. * 3에서 물건 가져 오기. * 3. 완료 : 트랜잭션 시작, 대상 대상의 방법을 호출하고, 공공 클래스 간격 대상 {public class intercepsor interceptor in revoctor interceptor em intercrector em intercrector em intercrector em intercrector em interceptor em intercrector em intercepton // 대상 클래스 개인 거래 거래; 공개 인터셉터 (오브젝트 대상, 트랜잭션 트랜잭션) {this.target = target; this.transaction = 트랜잭션; } / *** 프록시 인스턴스에서 인터페이스 메소드를 호출하는 메소드 인스턴스에 해당하는 대상 객체의 프록시 클래스의 프록시 클래스의 @param 프록시 인스턴스* @param args 프록시 인스턴스의 메소드 매개 변수 값으로 전달 된 객체 배열* @Throws throws (대상) (대상 prox, 메소드, 메소드, 메소드, 메소드) Throwable {String MethodName = method.getName (); if ( "saveperson".Equals (methodName) || "deleteperson".Equals (methodName) || "updatePerson".Equals (MethodName)) {this.transaction.beginTransaction (); // 트랜잭션 방법을 활성화합니다. invoke (target); // 대상 메소드를 호출 this.transaction.commit (); // 트랜잭션 제출} else {method.invoke (대상); } return null; }}시험
/*** 테스트 jdk 동적 프록시* @Author QJC*/public class testjdkproxy {@test public void testsave () {/*** 1. 대상 개체 생성* 2. 트랜잭션 생성* 3. 인터셉터 생성* 4. 동적으로 대상을 생성합니다. 트랜잭션 트랜잭션 = 새로운 트랜잭션 (); 인터셉터 인터셉터 = 새로운 인터셉터 (대상, 트랜잭션); /*** 매개 변수 1 : 대상 클래스* 매개 변수 2와 동일한 클래스 로더를 사용하는 코드에서 사용하는 클래스 로더를 설정하십시오. 파라미터 2 : 프록시 클래스에서 구현 한 인터페이스를 설정하고 대상 클래스* 매개 변수 3 : 콜백 개체를 설정하십시오. 프록시 오브젝트의 메소드가 호출되면 지정된 객체의 호출 메소드는*/ persondao persondao = (persondao) proxy.newproxyinstance (target.get.getClass (). getClassLoader (), getClass (). getInterfaces (), interceptor)라고합니다. persondao.saveperson (); }}요약 :
1. JDKPROXY에 의해 생성 된 프록시 클래스는 인터페이스를 구현하기 때문에 대상 클래스의 모든 메소드가 프록시 클래스에 포함됩니다.
2. 생성 된 프록시 클래스의 모든 방법은 대상 클래스의 모든 방법을 가로 채립니다. 인터셉터에서 호출 메소드의 내용은 프록시 클래스의 각 방법의 구성입니다.
3. JDKPROXY를 사용할 때는 인터페이스가 존재해야합니다.
4. 호출 메소드의 세 매개 변수는 호출 된 메소드의 API, 호출 된 메소드의 매개 변수 및 대상 클래스의 호출 된 메소드의 리턴 유형에 액세스 할 수 있습니다.
결점:
1. 차기 객체의 대상 방법을 호출하는 것을 제외하고는 인터셉터에서 함수는 비교적 단일입니다. 이 예에서는 거래 만 처리 할 수 있습니다.
2. 인터셉터에서 호출 메소드의 IF 판단 명령문은 실제 개발 환경에서 신뢰할 수 없다.
1.3 CGLIB 동적 프록시
이전 예제에서 persondaoimpl 클래스 및 트랜잭션 클래스 사용 (인터페이스 없음)
인터셉터 클래스를 작성하십시오
import net.sf.cglib.proxy.enhancer; import net.sf.cglib.proxy.methodinterceptor; import net.sf.sf.sf.cglib.proxy.methodproxy;/*** cglib proxy interceptor* @author qjc*/public class interceptor interceptor exprial object expert interceptor valment interceptor verctorcceptor*. // 프록시 대상 클래스 개인 거래 거래; 공개 인터셉터 (오브젝트 대상, 트랜잭션 트랜잭션) {this.target = target; this.transaction = 트랜잭션; } / ** * 대상 객체의 프록시 개체 생성 * * @return * / public Object createProxy () {// 코드 향상 Enhancer Enhancer = new enhancer (); //이 클래스는 프록시 객체 enhancer.setCallback (this)을 생성하는 데 사용됩니다. // 매개 변수는 인터셉터 Enhancer.setSuperClass (target.getClass ()); // 상위 클래스 return entercer.create ()를 설정합니다. // 프록시 객체 생성}/ *** @param obj 대상 객체 프록시 클래스의 인스턴스* @param 메소드 인스턴스 프록시 인스턴스에서 부모 클래스 메소드를 호출하는 @param args 프록시 인스턴스에서 메소드 매개 변수 값으로 전달 된 객체 배열* @param methodproxy를 사용하여 부모 클래스*/ problows methods (the obj interceter) Object [] args, MethodProxy MethodProxy) 던지기 가능 {this.transaction.begintransaction (); Method.invoke (대상); this.transaction.commit (); 널 리턴; }}시험
/*** 테스트 CGLIB 동적 프록시* CGLIB를 통해 생성 된 프록시 객체 인 프록시 클래스는 대상 클래스의 서브 클래스입니다* @Author qjc*/public class testcglibproxy {@test public void testsave () {object target = new persondaoimpl (); 트랜잭션 트랜잭션 = 새로운 트랜잭션 (); 인터셉터 인터셉터 = 새로운 인터셉터 (대상, 트랜잭션); persondaoimpl persondaoimpl = (persondaoimpl) interceptor.createproxy (); persondaoimpl.saveperson (); }}요약 :
1. CGLIB는 강력하고 고성능이며 고품질 코드 생성 클래스 라이브러리입니다. 런타임 중에 Java 클래스를 확장하고 Java 인터페이스를 구현할 수 있습니다.
2. CGLIB를 사용하여 대상 클래스의 서브 클래스로 프록시 클래스를 생성하십시오.
3. cglib를 사용하여 프록시 클래스를 생성하는 데 인터페이스가 필요하지 않습니다.
4. CGLIB에 의해 생성 된 프록시 클래스는 상위 클래스의 방법을 무시합니다.
5. 인터셉터의 인터셉트 메소드의 내용은 프록시 클래스에서 방법 본문 CGLIB와 JDK 동적 프록시의 차이입니다.
JDK :
대상 클래스와 프록시 클래스는 공통 인터페이스를 구현합니다.
인터셉터는 InvocationHandler 인터페이스를 구현해야하며,이 인터페이스의 Invoke 메소드 본문의 내용은 프록시 객체 메소드 본문의 내용입니다.
cglib :
대상 클래스는 프록시 클래스의 부모 클래스입니다.
인터셉터는 메소드 인 인터셉터 인터페이스를 구현해야하며 인터페이스의 인터셉트 메소드는 프록시 클래스의 메소드 본문이며 바이트 코드 향상 메커니즘은 프록시 객체를 만드는 데 사용됩니다.
2. 지향적 프로그래밍
OOP (객체 지향 프로그래밍) : 캡슐화, 상속, 다형성, 추상화
코드의 캡슐화, 기본 및 모듈 식 관리. 각 클래스에는 고유 한 기능이있을 수 있습니다. 문제가 잘못되면 누군가가 문제에 대해 논의 할만한 것을 찾으십시오. 수정의 관점에서 볼 때 코드를 직접 수정하는 것이 위험 할 수 있습니다. 이것은 장기 솔루션이 아닙니다. 가장 자연스러운 것은 유형 캡슐화에서 변경하는 것입니다. 그러나 새로운 유형과 오래된 시스템을 통합하는 방법이므로 계급 간의 혈액 관계를 설정해야합니다. 그러면 이것이 상속의 요구 사항입니다. 상속을 통해이 수업이 관련되어 있고 그들 사이에 아버지 아들 관계가 있음을 알 수 있습니다. 그런 다음 상속에 기초하여 다형성은 결정적인 특성을 가지고 있습니다. 따라서, 객체 지향의 가장 핵심 특징은 실제로 다형성이라고 생각된다. 처음 몇 명은 모두 토대를 마련하고 있습니다. 다형성은 핵심 특징입니다. 서브 클래스의 재 작성 방법은이 레벨의 확장을 나타내며 기존 시스템에 통합 될 수 있으며 정상적으로 작동 할 수 있습니다. 이것은이 수준, 새로운 방법, 오래된 시스템, 확장 및 재사용의 재사용입니다.
AOP (섹션 지향 프로그래밍) :
필수 프로그래밍은 사전 컴파일 된 런타임 동적 프록시를 통해 소스 코드를 수정하지 않고 프로그램에 기능을 동적으로 추가하는 기술입니다.
OOP와 AOP의 차이 :
OOP : 초록 캡슐화는 논리적 단위의 명확한 분할을 얻기 위해 비즈니스 처리 프로세스의 엔터티 및 해당 속성 및 동작에 대해 수행됩니다.
AOP : 비즈니스 프로세스에서 크로스 절단 논리를 추출합니다. 프로세스의 특정 단계 또는 단계에 직면하여 로직 프로세스의 부분 사이의 낮은 커플 링 분리 효과를 얻습니다. 이 두 디자인 아이디어는 목표에 필수적인 차이가 있습니다. AOP는 코드 블록 재사용을 달성했습니다.
스프링 AOP 프록시 메커니즘 :
1. 대상 객체가 여러 인터페이스를 구현하는 경우 Spring은 JDK의 java.lang.reflect.proxy 클래스 프록시를 사용합니다.
장점 : 인터페이스가 있기 때문에 시스템이 더 느슨하게 결합됩니다.
단점 : 각 대상 클래스에 대한 인터페이스를 만듭니다
2. 대상 객체가 인터페이스를 구현하지 않으면 Spring은 CGLIB 라이브러리를 사용하여 대상 객체의 서브 클래스를 생성합니다.
장점 : 프록시 클래스와 대상 클래스가 상속되기 때문에 인터페이스가 존재할 필요가 없습니다.
단점 : 인터페이스가 사용되지 않기 때문에 시스템의 결합은 JDK를 사용하는 동적 프록시만큼 좋지 않습니다.
Persondao 인터페이스, persondaoimpl 클래스 및 트랜잭션 클래스 사용
스프링 구성을 작성하십시오
<bean id = "persondao"> </bean> <bean id = "transaction"> </bean> <aop : config> <!-pointcut expression은 대상 클래스를 결정합니다-> <aop : pointcut expression = "execution (* cn.qjc.aop.xml.persondaoimpl. ref = "transaction"> <aop : 이전 메소드 = "begintransaction"pointcut-ref = "perform"/> <aop : after returning method = "commit"pointcut-ref = "perform"/> </aop : passe> </aop : config> </beans>
시험
/*** 테스트 스프링 동적 프록시* @Author qjc*/public class transactionTest {@test public void testsave () {ApplicationContext context = new ClassPathXmlApplicationContext ( "CN/qjc/aop/applicationContext.xml"); persondao persondao = (persondao) context.getbean ( "persondao"); persondao.saveperson (); }}스프링 AOP 원칙
1. 스프링 컨테이너가 시작되면 두 개의 콩이 적재되어 인스턴스화됩니다.
2. 스프링 컨테이너가 구성 파일을 <aop : config>로 구문 분석 할 때 포인트 컷 표현식을 구문 분석하고 포인트 컷 표현식에 따라 스프링 컨테이너 컨텐츠의 콩과 일치합니다.
3. 경기가 성공하면 Bean의 프록시 객체를 만듭니다.
4. 클라이언트가 context.getBean을 사용하여 객체를 얻는 경우 객체에 프록시 객체가있는 경우 프록시 객체를 반환합니다. 프록시 객체가 없으면 객체 자체를 반환합니다.
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.