Java 中的代理模式

我就是女王發表於2023-10-19

Java 中的代理模式

代理是設計模式中的一種,它允許物件以另一個物件的形式出現,透過代理物件來訪問原始物件。代理在許多應用程式中都得到廣泛使用,其中最常見的應用是在網路中實現遠端物件呼叫和日誌記錄。

Java 中也有許多使用代理模式的例子。Java 中的代理模式主要是透過以下三種方式實現的:


  靜態代理

靜態代理是透過在編譯階段建立代理類來實現的。代理類和原始類實現了同樣的介面,代理類透過呼叫原始類的方法來實現其自身的方法。靜態代理的優點是比較簡單直觀,但缺點是需要手動編寫代理類,當需要代理的方法增加或修改時,需要對代理類進行相應的修改。

下面是一個簡單的靜態代理示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

// 定義介面

interface UserManager {

     void add();

     void delete();

}

 

// 原始類

class UserManagerImpl implements UserManager {

     public void add() {

         System.out.println( "新增使用者" );

     }

 

     public void delete() {

         System.out.println( "刪除使用者" );

     }

}

 

// 代理類

class UserManagerProxy implements UserManager {

     private UserManager userManager;

 

     public UserManagerProxy(UserManager userManager) {

         this .userManager = userManager;

     }

 

     public void add() {

         System.out.println( "記錄日誌..." );

         userManager.add();

         System.out.println( "記錄日誌..." );

     }

 

     public void delete() {

         System.out.println( "記錄日誌..." );

         userManager.delete();

         System.out.println( "記錄日誌..." );

     }

}

 

// 客戶端程式碼

UserManager userManager = new UserManagerImpl();

UserManagerProxy userManagerProxy = new UserManagerProxy(userManager);

userManagerProxy.add();

userManagerProxy.delete();

  1. 動態代理

動態代理是在執行時透過反射機制建立代理類。和靜態代理不同,動態代理可以代理多個介面,並且不需要手動編寫代理類。動態代理的優點是比較靈活,但缺點是對效能有一定影響。

下面是一個簡單的動態代理示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

// 定義介面

interface UserManager {

     void add();

     void delete();

}

 

// 原始類

class UserManagerImpl implements UserManager {

     public void add() {

         System.out.println( "新增使用者" );

     }

 

     public void delete() {

         System.out.println( "刪除使用者" );

     }

}

 

// 代理類

class MyInvocationHandler implements InvocationHandler {

     private UserManager userManager;

 

     public MyInvocationHandler(UserManager userManager) {

         this .userManager = userManager;

     }

 

     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

         System.out.println( "記錄日誌..." );

         Object result = method.invoke(userManager, args);

         System.out.println( "記錄日誌..." );

         return result;

     }

}

 

// 客戶端程式碼

UserManager userManager = new UserManagerImpl();

InvocationHandler handler = new MyInvocationHandler(userManager);

UserManager proxy = (UserManager) Proxy.newProxyInstance(

     userManager.getClass().getClassLoader(),

     userManager.getClass().getInterfaces(),

     handler

);

proxy.add();

proxy.delete();

  1. CGLIB 代理

CGLIB 代理是透過生成原始類的子類來實現的。CGLIB 代理可以代理沒有實現介面的類,並且比動態代理快。但是,CGLIB 代理也有缺點,它要求原始類不能為 final 型別並且所有方法都不能為 final 型別。

下面是一個簡單的 CGLIB 代理示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

// 原始類

class UserManager {

     public void add() {

         System.out.println( "新增使用者" );

     }

 

     public void delete() {

         System.out.println( "刪除使用者" );

     }

}

 

// 代理類

class MyMethodInterceptor implements MethodInterceptor {

     private UserManager userManager;

 

     public MyMethodInterceptor(UserManager userManager) {

         this .userManager = userManager;

     }

 

     public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {

         System.out.println( "記錄日誌..." );

         Object result = method.invoke(userManager, args);

         System.out.println( "記錄日誌..." );

         return result;

     }

}

 

// 客戶端程式碼

UserManager userManager = new UserManager();

Enhancer enhancer = new Enhancer();

enhancer.setSuperclass(UserManager. class );

enhancer.setCallback( new MyMethodInterceptor(userManager));

UserManager proxy = (UserManager) enhancer.create();

proxy.add();

proxy.delete();

登入後複製

代理模式是一種常用的設計模式,它可以在不改變原始類的情況下為其提供額外的功能。在 Java 中,代理模式有三種實現方式:靜態代理、動態代理和 CGLIB 代理。不同的實現方式各有優缺點,可以根據具體情況選擇使用。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70033972/viewspace-2989985/,如需轉載,請註明出處,否則將追究法律責任。

相關文章