Rumah > Java > javaTutorial > java之动态代理

java之动态代理

高洛峰
Lepaskan: 2016-12-01 13:30:52
asal
1411 orang telah melayarinya

一、动态代理引入

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

package cn2;

  

public interface IUserDAO {

    /**

     * 登录方法

     */

    public void login();

      

    /**

     * 注册方法

     */

    public void register();

  

}

package cn2;

  

public class UserDAOImpl implements IUserDAO {

  

    @Override

    public void login() {

        System.out.println("用户登录");

  

    }

  

    @Override

    public void register() {

        System.out.println("用户注册");

    }

  

}

package cn2;

  

public class Test {

    public static void main(String[] args) {

        IUserDAO dao = new UserDAOImpl();

        dao.register();

        dao.login();

          

          

    }

}

Salin selepas log masuk

用户注册

用户登录


如果我要给每个方法都增加权限校验和日志记录的话,那么代码实现如下:

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

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

package cn2;

  

public interface IUserDAO {

    /**

     * 登录方法

     */

    public void login();

      

    /**

     * 注册方法

     */

    public void register();

  

}

package cn2;

  

public class UserDAOImpl implements IUserDAO {

  

    @Override

    public void login() {

        System.out.println("用户登录");

  

    }

  

    @Override

    public void register() {

        System.out.println("用户注册");

    }

  

}

package cn2;

  

public class UserDAOImpl2 implements IUserDAO {

    private void actionCheck(){

        System.out.println("权限检查");

    }

      

    private void record(){

        System.out.println("日志记录");

    }

      

    @Override

    public void login() {

        this.actionCheck();

        System.out.println("登录");

        this.record();

  

    }

  

    @Override

    public void register() {

        this.actionCheck();

        System.out.println("注册");

        this.record();

    }

  

}

package cn2;

  

public class Test {

    public static void main(String[] args) {

        IUserDAO dao = new UserDAOImpl2();

        dao.register();

        dao.login();

          

          

    }

}

Salin selepas log masuk

权限检查

注册

日志记录

权限检查

登录

日志记录


为什么要单独写一个类去实现接口,并增加权限校验和日志记录呢?因为我们在设计的时候,要保证对扩展功能开发,对修改代码关闭的原则。我定义了一个新的类去实现接口,就是想扩展原来接口的功能,而不是在原有的实现类上修改。

但是,如果都这样设计,是很可怕的事情,如果需求一旦变更,那我们需要定义好多好多的实现类,太复杂了。怎么办?


在生活中,我们会遇到很多问题,比如:我要租房子,但是我不认识房东,怎么办?找中介。同样的道理,我自己不想在修改代码去增加权限检查和日志记录的功能,那么我找一个代理对象去帮我实现不就可以了吗?

动态代理:就是在程序运行过程中产生的这个对象。

在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口接可以生成动态代理对象。JDK只针对接口做代理。

Proxy类中的方法创建动态代理对象

1

public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)

Salin selepas log masuk

最终会调用InvocationHandler的方法

1

Object invoke(Object proxy,Method method,Object[] args)

Salin selepas log masuk

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

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

package cn2;

  

public interface IUserDAO {

    /**

     * 登录方法

     */

    public void login();

      

    /**

     * 注册方法

     */

    public void register();

  

}

package cn2;

  

public class UserDAOImpl implements IUserDAO {

  

    @Override

    public void login() {

        System.out.println("用户登录");

  

    }

  

    @Override

    public void register() {

        System.out.println("用户注册");

    }

  

}

package cn2;

  

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

  

public class MyInvocationHandler implements InvocationHandler {

      

    private Object target;

    public MyInvocationHandler(Object target) {

        this.target = target;

    }

      

    /**

     *返回动态代理对象

     */

    @Override

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

            throws Throwable {

          

        System.out.println("权限检查");

          

        Object invoke = method.invoke(target, args);

          

        System.out.println("日志记录");

        return invoke;

    }

  

}

package cn2;

  

import java.lang.reflect.Proxy;

  

public class Test {

    public static void main(String[] args) {

        //使用动态代理之前

        IUserDAO dao = new UserDAOImpl();

        dao.register();

        dao.login();

          

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

          

        //使用动态代理之后

          

        IUserDAO proxy = (IUserDAO)Proxy.newProxyInstance(dao.getClass().getClassLoader(), dao.getClass().getInterfaces(), new MyInvocationHandler(dao));

        proxy.register();

        proxy.login();

          

    }

}

Salin selepas log masuk

   

用户注册

用户登录

-------------------

权限检查

用户注册

日志记录

权限检查

用户登录

日志记录


Label berkaitan:
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Isu terkini
Bolehkah java digunakan sebagai bahagian belakang web?
daripada 1970-01-01 08:00:00
0
0
0
Pasang JAVA
daripada 1970-01-01 08:00:00
0
0
0
Tidak dapat memasang java
daripada 1970-01-01 08:00:00
0
0
0
Bagaimanakah php melaksanakan penyulitan sha1 java?
daripada 1970-01-01 08:00:00
0
0
0
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan