[자바 기반] 동적 에이전트 가 AOP 의 제어 업 무 를 실현 합 니 다.

7765 단어 【Java방울
머리말
디자인 모델 을 배 울 때 정적 대리 와 동적 대리 에 대해 연 구 를 한 적 이 있 는데 정적 대 리 는 이해 하기 쉽 고 코드 도 간단 하 다.그러나 동적 프 록 시 코드 는 상대 적 으로 복잡 하고 그 당시 수준 에 따라 잘 알 지 못 했다.이번 에는 자바 의 동적 대 리 를 분석 해 보 겠 습 니 다.
정적 에이전트 단점
정적 대 리 는 간단 하지만 유연 하지 않 습 니 다. 사용 하려 면 모든 클래스 에 프 록 시 클래스 를 만들어 야 합 니 다.사용 하기에 매우 불편 하고 대량의 코드 가 중복 되 어 실제 응용 에서 광범 위 하지 않다.동적 대리 의 등장 은 이런 문 제 를 해결 했다.
동적 에이전트 분석
자바 의 동적 에이전트 에는 두 가지 중요 한 클래스 나 인터페이스 가 있 습 니 다. 하 나 는 Invocation Handler (Interface) 이 고 다른 하 나 는 Proxy (Class) 입 니 다. 이 클래스 와 인 터 페 이 스 는 우리 의 동적 대 리 를 실현 하 는 데 필요 한 것 입 니 다.
모든 동적 프 록 시 클래스 는 Invocation Handler 라 는 인 터 페 이 스 를 실현 해 야 하고 모든 프 록 시 클래스 의 인 스 턴 스 는 하나의 handler 와 연결 되 어 있 습 니 다. 우리 가 프 록 시 대상 을 통 해 하나의 방법 을 호출 할 때 이 방법의 호출 은 Invocation Handler 라 는 인터페이스의 invoke 방법 으로 전 송 됩 니 다.
저 희 는 invoke 방법 에서 다른 작업 을 할 수 있 습 니 다. 예 를 들 어 업무 통제, 로그 출력 등 을 해서 AOP 의 효 과 를 실현 할 수 있 습 니 다.여기 서 Servlet 의 Filter 를 언급 해 야 합 니 다. AOP 의 효 과 를 실현 할 수 있 기 때 문 입 니 다. 동적 에이전트 와 달리 Filter 는 차단기 의 원 리 를 바탕 으로 목표 자원 에 접근 하기 전에 방문 요청 과 응답 을 차단 한 다음 에 몰래 작업 을 수행 합 니 다.이 두 가지 방식 을 비교 해 보면 사용 장면 이 다 르 고 Filter 는 프론트 JSP, Servlet 에 적용 된다.동적 에이전트 가 배경 에 적용 되 는 서비스 방법
프 록 시 라 는 클래스 의 역할 은 프 록 시 대상 을 동적 으로 만 드 는 클래스 입 니 다. 많은 방법 을 제공 합 니 다. 그러나 우리 가 가장 많이 사용 하 는 것 은 뉴 프 록 시 인 스 턴 스 라 는 방법 입 니 다. 그 역할 은 동적 인 프 록 시 대상 을 얻 는 것 입 니 다.
응용 실례
다음은 동적 대 리 를 통 해 AOP 를 실현 하고 사 무 를 통일 적 으로 통제 하 는 구체 적 인 예 이다.동적 프 록 시 사용 전후 코드 의 변 화 를 비교 해 AOP 의 역할 을 느 낄 수 있다.
1. 원래 의 manager 방법 은 모든 사무 코드 를 추가 하고 사무 코드 가 대량으로 중복 되 어야 합 니 다.
    public void delFlowCard(String[] flowCardVouNos)
            throws ApplicationException
    {
        Connection conn = null;
        try
        {
            //   Connection
            conn = ConnectionManager.getConnection();

            //     
            ConnectionManager.beginTransaction(conn);

            //        
            flowCardDao.delFlowCardDetail(flowCardVouNos);

            //        
            flowCardDao.delFlowCardMaster(flowCardVouNos);

            //     
            ConnectionManager.commitTransaction(conn);
        }
        catch (DaoException e)
        {
            //     
            ConnectionManager.rollbackTransaction(conn);
            throw new ApplicationException("       !");
        }
        finally
        {
            //   Connection  ThreadLocal   
            ConnectionManager.closeConnection();
        }
    }

2. 동적 에이 전 트 를 사용 하여 AOP 효 과 를 실현 합 니 다.
① 프 록 시 클래스 만 들 기:
/**
 * @ClassName: TransactionHandler
 * @Description:         
 * @author:   -   
 * @date: 2015-10-11   2:59:15
 */
public class TransactionHandler implements InvocationHandler
{
    private Object targetObject;

    public Object newProxyInstance(Object targetObject)
    {
        this.targetObject = targetObject;
        //  Proxy ,               
        return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
                targetObject.getClass().getInterfaces(), this);
    }

     // invoke          
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable
    {
        Connection conn = null;
        Object ret = null;
        try
        {
            //  ThreadLocal   Connection
            conn = ConnectionManager.getConnection();
            if (method.getName().startsWith("add")
                    || method.getName().startsWith("del")
                    || method.getName().startsWith("modify"))
            {
                //         
                ConnectionManager.beginTransaction(conn);
            }
            //              
            ret = method.invoke(targetObject, args);
            if (!conn.getAutoCommit())
            {
                //     
                ConnectionManager.commitTransaction(conn);
            }
        }
        catch (ApplicationException e)
        {
            //     
            ConnectionManager.rollbackTransaction(conn);
            throw e;
        }
        catch (Exception e)
        {
            e.printStackTrace();
            if (e instanceof InvocationTargetException)
            {
                InvocationTargetException ete = (InvocationTargetException) e;
                throw ete.getTargetException();
            }
            //     
            ConnectionManager.rollbackTransaction(conn);
            throw new ApplicationException("    !");
        }
        finally
        {
            ConnectionManager.closeConnection();
        }
        return ret;
    }

}

② servlet 에서 호출 프 록 시 클래스 만 들 기
    public void init() throws ServletException
    {
        flowCardManager = (FlowCardManager) getBeanFactory().getServiceObject(
                FlowCardManager.class);
        //     
        TransactionHandler transactionHandler = new TransactionHandler();
        //          
            flowCardManager = (FlowCardManager) transactionHandler
                .newProxyInstance(flowCardManager);
    }

이후 manager 를 호출 하 는 방법 은 에이전트 클래스 로 이동 하여 해당 하 는 사무 작업 을 수행 한 다음 에 목표 방법 을 계속 호출 합 니 다.이렇게 하면 우리 의 사무 코드 는 한 번 만 쓰 면 모든 수 요 를 만족 시 킬 수 있 고 코드 의 재 활용 을 완성 할 수 있 으 며 유지 하면 이 사무 대리 류 만 유지 하면 됩 니 다.이것 이 바로 절단면 프로 그래 밍 을 위 한 장점 이다.

좋은 웹페이지 즐겨찾기