静态代理与动态代理模式

Posted yy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了静态代理与动态代理模式相关的知识,希望对你有一定的参考价值。

代理(Proxy)设计模式简介:

提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能.
这里使用到编程中的一个思想:不要随意去修改别人已经写好的代码或者方法,如果需改修改,可以通过代理的方式来扩展该方法
举个例子来说明代理的作用:假设我们想邀请一位明星,那么并不是直接连接明星,而是联系明星的经纪人,来达到同样的目的.明星就是一个目标对象,他只要负责活动中的节目,而其他琐碎的事情就交给他的代理人(经纪人)来解决.这就是代理思想在现实中的一个例子

静态代理:

静态代理在使用时,需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类.

    class Program
    {
        static void Main(string[] args)
        {
            Member member = new Member() { Id=1,Name="test member"};
            IMemberService baseMemberService = new MemberServiceImpl();

            //代理原有业务类
            MemberSerivceImplStaticProxy memberService = new MemberSerivceImplStaticProxy(baseMemberService);
            //遵守接口契约
            string result = memberService.Create(member);

            System.Console.WriteLine(result);
            System.Console.ReadKey();
        }
    }

    class Member {
        public int Id { get; set; }
        public String Name { get; set; }

        public override string ToString(){
            return string.Format("Member[Id={0},Name={1}]", this.Id, this.Name);
        }
    }

    interface IMemberService {
        string Create(Member member);
    }

    class MemberServiceImpl : IMemberService {
        public string Create(Member member){
            Console.WriteLine("create member:"+member);
            return "SUCCESS";
        }
    }

    class MemberSerivceImplStaticProxy {
        private IMemberService target;

        public MemberSerivceImplStaticProxy(IMemberService target) {
            this.target = target;
        }

        public string Create(Member member){
            before(member);
            string result= target.Create(member);
            after(member);

            return result;
        }

        private void before(Member member){
            Console.WriteLine("before " + member);
        }

        private void after(Member member){
            Console.WriteLine("after " + member);
        }
    }

动态代理:

动态代理有以下特点:
1.代理对象,不需要实现接口
2.代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象(需要我们指定创建代理对象/目标对象实现的接口的类型)
3.动态代理也叫做:JDK代理,接口代理

    class Program
    {
        static void Main(string[] args)
        {
            Member member = new Member() { Id=1,Name="test member"};
            IMemberService baseMemberService = new MemberServiceImpl();
            
            //代理原有业务类
            IMemberService memberService = (IMemberService)new MemberServiceImplDynamicProxy(baseMemberService).GetTransparentProxy();
            //遵守接口契约
            string result = memberService.Create(member);

            System.Console.WriteLine(result);
            System.Console.ReadKey();
        }
    }

    class Member {
        public int Id { get; set; }
        public String Name { get; set; }

        public override string ToString(){
            return string.Format("Member[Id={0},Name={1}]", this.Id, this.Name);
        }
    }

    interface IMemberService {
        string Create(Member member);
    }

    class MemberServiceImpl : IMemberService {
        public string Create(Member member){
            Console.WriteLine("create member:"+member);
            return "SUCCESS";
        }
    }

    class MemberServiceImplDynamicProxy : System.Runtime.Remoting.Proxies.RealProxy {
        private IMemberService target;

        public MemberServiceImplDynamicProxy(IMemberService target) : base(typeof(IMemberService)){
            this.target = target;
        }

        public override System.Runtime.Remoting.Messaging.IMessage Invoke(System.Runtime.Remoting.Messaging.IMessage msg){
            System.Runtime.Remoting.Messaging.IMethodCallMessage callMessage = (System.Runtime.Remoting.Messaging.IMethodCallMessage)msg;
            Member member = callMessage.Args[0] as Member;

            before(member);
            object returnValue = callMessage.MethodBase.Invoke(this.target, callMessage.Args);
            after(member);

            return new System.Runtime.Remoting.Messaging.ReturnMessage(returnValue, new object[0], 0, null, callMessage);
        }

        private void before(Member member){
            Console.WriteLine("before " + member);
        }

        private void after(Member member){
            Console.WriteLine("after " + member);
        }
    }

 为了让动态代理类更通用,可以对其调整为如下:

    class DynamicProxyFactory : System.Runtime.Remoting.Proxies.RealProxy
    {
        private object target;

        public DynamicProxyFactory(object target, Type targetType)
            : base(targetType)
        {
            this.target = target;
        }

        public override System.Runtime.Remoting.Messaging.IMessage Invoke(System.Runtime.Remoting.Messaging.IMessage msg)
        {
            System.Runtime.Remoting.Messaging.IMethodCallMessage callMessage = (System.Runtime.Remoting.Messaging.IMethodCallMessage)msg;

            before(this.target);
            object returnValue = callMessage.MethodBase.Invoke(this.target, callMessage.Args);
            after(this.target);

            return new System.Runtime.Remoting.Messaging.ReturnMessage(returnValue, new object[0], 0, null, callMessage);
        }

        private void before(object member)
        {
            Console.WriteLine("before " + member);
        }

        private void after(object member)
        {
            Console.WriteLine("after " + member);
        }
    }

对应客户端调用时也要变,变为如下:

    class Program
    {
        static void Main(string[] args)
        {
            Member member = new Member() { Id = 1, Name = "test member" };
            IMemberService baseMemberService = new MemberServiceImpl();

            //代理原有业务类
            IMemberService memberService = (IMemberService)new DynamicProxyFactory(baseMemberService, typeof(IMemberService)).GetTransparentProxy();
            //遵守接口契约
            string result = memberService.Create(member);

            System.Console.WriteLine(result);
            System.Console.ReadKey();
        }
    }

 

以上是关于静态代理与动态代理模式的主要内容,如果未能解决你的问题,请参考以下文章

代理模式的概念

Java动态代理与静态代理的定义与区别??

代理模式(静态代理动态代理)代码实战(详细)

Spring AOP JDK动态代理与CGLib动态代理区别

代理模式-静态代理与动态代理

java静态代理与动态代理