동적 에이전트의 깊은 이해

21336 단어 동적 에이전트
요약 패브릭:
정적 프록시 모드의 단점:
1. 한 시스템에 100Dao가 있으면 100개의 프록시 대상을 만든다
2. 만약에 하나의dao에서 많은 방법이 사무를 필요로 한다면 대리 대상의 방법에는 중복 코드가 많다
3. 첫 번째와 두 번째 점에서 알 수 있듯이proxy의 중용성이 강하지 않다
 
정적 에이전트가 개발 수요를 충족시키지 못하기 때문에 동적 에이전트를 끌어냅니다
 
동적 프록시 모드:
1. 생성된 대리 대상과 목표 대상이 공통된 인터페이스를 실현했다.
jdk 동적 에이전트
2. 프록시 대상은 목표 대상의 하위 클래스이다
       hibernate: Person person = session.load(Person.class,1L);  javassisit
spring:cglib 동적 에이전트
 
jdk의 동적 에이전트:
1、jdk의 API로 만들었기 때문에
2. 프록시 대상은 동적으로 발생한다
cglib에서 발생하는 프록시 클래스는 목표 클래스의 하위 클래스입니다
 
참고 사항:
1. 차단기에서 invoke 방법체의 내용은 대리 대상 방법체의 내용이다
2. 클라이언트가 프록시 대상을 집행하는 경우.방법 시 차단기의 invoke 방법체에 들어갑니다
3. 차단기에서 invoke 방법의 method 매개 변수는 호출할 때 값을 부여한다
 
aop:
1. 칼국수
사무, 로그, 보안 프레임워크, 권한 등이 모두 절면이다
2. 통지
칼국수의 방법은 바로 통지입니다.
3. 목표 클래스
4. 접점
접근점에 부합되어야만 통지와 목표 방법을 결합시킬 수 있다
5. 직입:
대리 대상을 형성하는 방법의 과정
         
 
이점:
사무, 로그, 보안 프레임워크, 권한, 목표 방법 간에 완전히 느슨하게 결합되어 있다
 
 
jdk의 동적 에이전트 예
PersonDao.java
1 package cn.itcast.jdkproxy.sh;
2 
3 public interface PersonDao {
4     public void savePerson();
5     public void updatePerson();
6     public void deletePerson();
7 }

PersonDaoImpl.java
 1 package cn.itcast.jdkproxy.sh;
 2 
 3 public class PersonDaoImpl implements PersonDao{
 4     public void deletePerson() {
 5         System.out.println("delete person");
 6     }
 7     public void savePerson() {
 8         System.out.println("save person");
 9     }
10     public void updatePerson() {
11         System.out.println("update person");
12     }
13 }

Transaction.java
 1 package cn.itcast.jdkproxy.sh;
 2 
 3 public class Transaction {
 4     public void beginTransaction(){
 5         System.out.println("  ");
 6     }
 7     public void commit(){
 8         System.out.println(" ");
 9     }
10 }

PersonInterceptor.java
 1 package cn.itcast.jdkproxy.sh;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 
 6 /**
 7  *  
 8  * @author Think
 9  *   1、 
10  *   2、 
11  *   3、 
12  *   4、 invoke 
13  *
14  */
15 public class PersonInterceptor implements InvocationHandler{
16     
17     private Object target;// 
18     private Transaction transaction;// 
19     
20     public PersonInterceptor(Object target,Transaction transaction){
21         this.target = target;
22         this.transaction = transaction;
23     }
24     
25 
26     @Override
27     public Object invoke(Object proxy, Method method, Object[] args)
28             throws Throwable {
29         // TODO Auto-generated method stub
30         this.transaction.beginTransaction();
31         method.invoke(this.target, args);// 
32         this.transaction.commit();
33         return null;
34     }
35 
36 }

ProxyTest.java
 1 package cn.itcast.jdkproxy.sh;
 2 
 3 import java.lang.reflect.Proxy;
 4 
 5 import org.junit.Test;
 6 import org.springframework.context.ApplicationContext;
 7 import org.springframework.context.support.ClassPathXmlApplicationContext;
 8 
 9 public class ProxyTest {
10     @Test
11     public void test(){
12         Object target = new PersonDaoImpl();
13         Transaction transaction = new Transaction();
14         PersonInterceptor interceptor = new PersonInterceptor(target, transaction);
15         /**
16          * 1、 
17          * 2、 
18          * 3、 
19          */
20         PersonDao personDao = (PersonDao)Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), interceptor);
21         personDao.deletePerson();
22     }
23 }

jdk의 동적 에이전트를 실현합니다. 상기 예의 개선은PersonInterceptor에서 가능합니다.java에 구성원 함수 추가
private List interceptors;
그리고 절단면이 모두 인터셉터 인터페이스를 계승하도록 합니다. 이 인터페이스는 스스로 정의한 것입니다.
 
예제 개선 사항:
1 package cn.itcast.jdkproxy.salary;
2 
3 public interface Interceptor {
4     public void interceptor();
5 }

 
기타 클래스
 1 package cn.itcast.jdkproxy.salary;
 2 
 3 public class Logger implements Interceptor{
 4 
 5     @Override
 6     public void interceptor() {
 7         // TODO Auto-generated method stub
 8         System.out.println("logging");
 9     }
10     
11 }

 
 
 1 package cn.itcast.jdkproxy.salary;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 import java.util.List;
 6 
 7 public class SalaryInterceptor implements InvocationHandler{
 8 
 9     
10     private Object target;
11     
12     private List<Interceptor> interceptors;
13     
14     public SalaryInterceptor(Object target,List<Interceptor> interceptors){
15         this.target = target;
16         this.interceptors = interceptors;
17     }
18     
19     @Override
20     public Object invoke(Object proxy, Method method, Object[] args)
21             throws Throwable {
22         for(Interceptor interceptor:interceptors){
23             interceptor.interceptor();
24         }
25         method.invoke(this.target, args);
26         return null;
27     }
28 
29 }

클라이언트 테스트 클래스
 1 package cn.itcast.jdkproxy.salary;
 2 
 3 import java.lang.reflect.Proxy;
 4 import java.util.ArrayList;
 5 import java.util.List;
 6 
 7 import org.junit.Test;
 8 
 9 public class SalaryTest {
10     @Test
11     public void test(){
12         Object target = new SalaryManagerImpl();
13         Logger logger = new Logger();
14         Security security = new Security();
15         Privilege privilege = new Privilege();
16         List<Interceptor> interceptors = new ArrayList<Interceptor>();
17         interceptors.add(logger);
18         interceptors.add(security);
19         interceptors.add(privilege);
20         SalaryInterceptor interceptor = new SalaryInterceptor(target, interceptors);
21         SalaryManager salaryManager = (SalaryManager)Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), interceptor);
22         salaryManager.showSalary();
23     }
24 }

 

좋은 웹페이지 즐겨찾기