靜態代理和動態代理

靜態代理和動態代理

介紹

在一些情況下,客戶端不想或者不能夠直接引用一個對象,而代理對象就可以在客戶端和目標對象之間起到中介的作用.

代理設計模式:可以先簡單理解爲代理商或中介的概念,比如上網我們可能就會使用代理服務器去上網.

典型的代理設計模式:proxy對象不是真正的服務提供者,它只是負責中間一些驗證監控或日誌之類的操作.

備註:代理模式分爲兩種靜態代理和動態代理

抽象主題角色:聲明瞭真實主題和代理主題的共同接口 
代理主題(Proxy):代理主題角色內部含有對真實主題的引用,從而在任何時候可以操作真實主題對象 
真實主題:定義了代理角色所代表的真實對象

靜態代理

Net上網Subject

    /**
     * 
     * @author xuyi3
     * @2016年9月13日 @上午9:35:31
     * @Net     上網類(上網Subject)
     * @功能說明:<br>
     * @春風十里不如你
     * @備註
     */
    public class Net
    {
            /**
             * 上網方法
             */
            public void internet()
            {
                System.out.println("internet ... ");
            }
    }

Net上網代理對象

/**
 * 
 * @author xuyi3
 * @2016年9月13日 @上午9:31:17
 * @NetProxy
 * @功能說明:<br>
 * @春風十里不如你
 * @備註
 */
public class NetProxy
{

        //Net引用
        private Net net;
        public NetProxy()
        {
        }
        /**
         * <h3>上網方法</h3>
         * @param username
         * @param password
         */
        public void internet(String username, String password)
        {
            //首先進行身份驗證
            boolean verifySuccess = verifyIdentity(username, password);
            if (verifySuccess)
            {
                if (net == null)
                {
                    net = new Net();
                }
                net.internet();
            }
            //上完網之後統計流量信息
            countInternetTraffic();
        }
        /**
         * <h3>驗證上網者身份</h3>
         * @param username      用戶賬號
         * @param password      用戶密碼
         * @return
         */
        private boolean verifyIdentity(String username, String password)
        {
            System.out.println("====身份驗證====");
            //驗證上網者身份
            return true;
        }
        /**
         * <h3>統計上網信息</h3>
         * @return
         */
        private int countInternetTraffic()
        {
            System.out.println("====統計流量====");
            //計算上網流量
            return 0;
        }
}

NetApp

/**
 * @author xuyi3
 * @2016年9月13日 @上午9:32:43
 * @NetApp
 * @功能說明:<br>
 * @春風十里不如你
 * @備註
 */
public class NetApp
{
        public static void main(String[] args)
        {
            //初始化上網代理對象
            NetProxy netProxy = new NetProxy();
            netProxy.internet("admin", "123");
        }
}

動態代理

舉例:數據庫事務操作時,每次操作都要先開啓事務然後再提交事務,這樣模板式的代碼頻繁的出現,既不安全也繁瑣.

可以使用動態代理來幫助我們處理這些樣式代碼,即AOP面向切面編程。

應用

UserService

/**
 * 
 * @author xuyi3
 * @2016年9月13日 @上午10:27:21
 * @UserService
 * @功能說明:<br>
 * @春風十里不如你
 * @備註
 */
public interface UserService
{
    void addUser(String username);
}

UserServiceImpl

/**
 * 
 * @author xuyi3
 * @2016年9月13日 @上午10:25:27
 * @UserServiceImpl
 * @功能說明:
 * @春風十里不如你
 * @備註
 */
public class UserServiceImpl implements UserService
{
        public void addUser(String username)
        {
            System.out.println("addUser ... username:" + username);
        }
}

PersonService

/**
 * 
 * @author xuyi3
 * @2016年9月13日 @上午10:27:54
 * @PersonService
 * @功能說明:<br>
 * @春風十里不如你
 * @備註
 */
public interface PersonService
{
    void addPerson(String name);
}

PersonServiceImpl

/**
 * 
 * @author xuyi3
 * @2016年9月13日 @上午10:25:13
 * @PersonServiceImpl
 * @功能說明:<br>
 * @春風十里不如你
 * @備註
 */
public class PersonServiceImpl implements PersonService
{

        public void addPerson(String name)
        {
            System.out.println("addPerson... name:" + name);
        }

}

ObjectProxy

/**
 * 看其名字ObjectProxy就可以知道其是萬能代理對象
 * @author xuyi3
 * @2016年9月13日 @上午10:28:30
 * @ObjectProxy
 * @功能說明:<br>
 * @春風十里不如你
 * @備註
 */
public class ObjectProxy implements InvocationHandler
{

        //待代理對象
        private Object target;

        /**
         * <h3>通過構造方法傳入需要使用的主題實現類對象</h3>
         * 
         * @param target
         */
        public ObjectProxy(Object target)
        {
            this.target = target;
        }

        /**
         * <h3>使用Proxy創建代理對象實例</h3>
         * 核心方法
         * @return
         */
        public Object createProxy()
        {
            return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
        }

        /**
         * @param proxy     
         * @param method    
         * @param args      
         * @return      
         * @throws Throwable
         */
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
        {

            beforeInvoke();
            //      System.out.println(method.getName());// 輸出執行方法名
            Object result = method.invoke(target, args);
            afterInvoke();
            return result;

        }

        private void beforeInvoke()
        {
            System.out.println("begin事務 ...");
        }

        private void afterInvoke()
        {
            System.out.println("commit事務 ...");
        }

}

MainApp

/**
 * 
 * @author xuyi3
 * @2016年9月13日 @上午9:53:40
 * @MainApp
 * @功能說明:<br>
 * @春風十里不如你
 * @備註
 */
public class MainApp
{
        public static void main(String[] args) throws Exception
        {
            UserService userService = new UserServiceImpl();
            ObjectProxy objectProxy1 = new ObjectProxy(userService);
            UserService userServiceProxy = (UserService) objectProxy1.createProxy();
            userServiceProxy.addUser("admin");

            System.out.println("------------------");

            PersonService personService = new PersonServiceImpl();
            ObjectProxy objectProxy2 = new ObjectProxy(personService);
            PersonService personServiceProxy = (PersonService) objectProxy2.createProxy();
            personServiceProxy.addPerson("xuyi");
        }
}

總結

代理設計模式是現實開發中比較常使用到的,同時動態代理也是Spring AOP面向切面技術的基礎理論。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章