num06---代理模式

代理模式,比较好理解,关键点就是,被代理类 和 代理类 实现同一个接口,接口中定义着想要实现的被代理的方法,在代理类中引入 被代理类 对象,

最后直接调用代理类的方法即可实现代理功能。【cglib 代理 也是动态代理,但是不需要实现接口】

1、静态代理

  

   

 案例代码:

  

1

2

3

4

5

public interface IAccountService {

    //主业务逻辑,转账

    void transfer();

}

  

1

2

3

4

5

6

public class AccountServiceImpl implements IAccountService{

    @Override

    public void transfer() {

        System.out.println("完成转账业务");

    }

}

  

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

@description 转账代理类

 */

public class AccountProxy implements IAccountService {//代理类要实现转账接口

    //代理类 要把被代理的对象作为一个成员变量,将目标对象引入代理类

    //声明业务接口对象

    private IAccountService target;

     

    public AccountProxy() {

        super();

    }

    public AccountProxy(IAccountService target) {

        super();

        this.target = target;

    }

    /**

     * @createTime  2019年11月8日下午2:48:50

     * @description 代理方法,对目标方法进行增强

     */

    @Override

    public void transfer() {

        System.out.println("增强:身份验证");

        target.transfer();

    }

}

  测试:

1

2

3

4

5

6

7

public static void main(String[] args) {

    //创建目标对象

    IAccountService target = new AccountServiceImpl();

    //创建代理对象

    IAccountService proxy = new AccountProxy(target);

    proxy.transfer();

}

  

 2、动态代理

 

 

 代码:

 

 

 

3、Cglib代理

 代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

*

 * cglib  动态代理       老父亲的亲儿子,子类继承父类,增强后,作为代理对象,

 * 父子之间不需要接口去事先约定让子类增强什么,而是父让子增强什么,儿子就增强什么。

 *

 */

public class AccountService {

    //目标方法

    public void transfer() {

        System.out.println("调用dao层,完成转账。");

    }

    //目标方法

    public void getBalance() {

        System.out.println("调用dao层,查询余额");

    }

}

 

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

@description cglib 代理类生成工厂,cglib代理  原理  ,生成目标类的增强子类

 *

 *  实现 MethodInterceptor 接口

 */

public class AccountServiceCglibProxyFactory implements  MethodInterceptor{

     

    //1、生成目标类的成员变量,以及 构造方法

    private AccountService target;<br>

    public AccountServiceCglibProxyFactory(AccountService target) {

        super();

        this.target = target;

    }

    //2、定义代理生成方法,用于创建代理对象

     AccountService createProxy() {

        //创建增强器

        Enhancer enhancer = new Enhancer();

        //初始化增强器,将目标类 指定为 父类

        enhancer.setSuperclass(AccountService.class);

        //初始化增强器,设置回调

        enhancer.setCallback(this);     //MethodInterceptor 接口继承自 Callback

        //使用增强器创建代理对象

        return (AccountService)enhancer.create();

    }

     

    //回调接口方法,在此完成对目标类的增强

    /**

     * @author      ayfei

     * @createTime  2019年11月11日下午1:24:31

     * @param   proxy  代理对象

     * @param   method  代理对象的方法,即增强过的业务方法

     * @param   args[]  方法参数

     * @param   methodProxy  代理对象方法的代理对象

     */

    @Override

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

        //若为transfer方法,则进行增强

        if("transfer".equals(method.getName())) {

            //增强业务逻辑,打印时间

            System.out.println(System.currentTimeMillis());

            //方式一   通过调用代理类proxy,即目标类的子类的父类方法执行,  两种方式等效

            //Object result = methodProxy.invokeSuper(proxy, args);

            //方式二   直接调用目标对象的业务方法执行

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

            return result;

        }

        //其他方法不增强,则执行目标类的业务方法

        return method.invoke(target, args);

    }

}

  

 

1

2

3

4

5

6

7

8

9

10

11

*/

public class TestClass {

    public static void main(String[] args) {

        //创建目标对象

        AccountService target = new AccountService();

        AccountService createProxy = new AccountServiceCglibProxyFactory(target).createProxy();

         

        createProxy.transfer();

        createProxy.getBalance();

    }

}

  

发布了104 篇原创文章 · 获赞 1 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/xiaoanzi123/article/details/104390167
num