设计模式——2.代理模式

前言:

    由于复习mybatis知识点的时候,mapper代理涉及到了代理模式,于是阅读了相关资料以后,小结一下代理模式。

1.UML图


2.角色分类

    2.1 抽象对象:是目标对象和代理对象的抽象父类。

    2.2 目标对象:要被代理的对象,实现了抽象对象。比如未成年人

    2.3 代理对象:作为中介,接收外界指令,传递给代理对象(生成代理对象)。比如未成年人看护人。

3.常见的代理模式

    3.1 静态代理(目标对象和代理对象都要实现抽象父类)

    抽象对象:接口声明playgame方法

public interface IUserDao {
	void playgame();
}

    目标对象:未成年人实现playgame 方法

public class UserDaoImp implements IUserDao {

	public void playgame() {
		 System.out.println("----玩儿童游戏!----");
	}

}

    代理对象:未成年人人监护人,也实现palygame方法,并且生成了为目标对象,以此对目标对象进行操作。

public class UserDaoProxy implements IUserDao {
	private IUserDao  target;
	 public UserDaoProxy(IUserDao target){
	        this.target=target;
	    }
	@Override
	public void playgame() {
		// TODO Auto-generated method stub
		System.out.println("开始事务...");
        target.playgame();//执行目标对象的方法
        System.out.println("提交事务...");
	}

}

    测试类

public class Test {
	public static void main(String[] args) {
        //目标对象
		IUserDao target = new UserDaoImp();

        //代理对象,把目标对象传给代理对象,建立代理关系
        UserDaoProxy proxy = new UserDaoProxy(target);

        proxy.playgame();//执行的是代理的方法
    }
}

    3.2 动态(JDK)代理

        ①代理对象无需实现抽象父类

        ②代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象

        ③引入 java.lang.reflect.Proxy 包

    

    抽象对象:接口声明playgame方法

public interface IUserDao {
	void playgame();
}

    目标对象:未成年人实现playgame 方法

public class UserDaoImp implements IUserDao {

	public void playgame() {
		 System.out.println("----玩儿童游戏!----");
	}

}

     代理工厂:相当静态代理中的代理对象

public class ProxyFactory {
	//维护一个目标对象,静态代理是一个具体的类
    private Object target;
    public ProxyFactory(Object target){
        this.target=target;
    }
  //给目标对象生成代理对象
    public Object getProxyInstance(){
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                
					@Override
					public Object invoke(Object proxy, Method method,
							Object[] args) throws Throwable {
						 System.out.println("开始事务2");
	                        //执行目标对象方法
	                        Object returnValue = method.invoke(target, args);
	                        System.out.println("提交事务2");
	                        return returnValue;
					}
                }
        );
    }
}

    测试类

//动态代理也称为	:JDK代理,接口代理
public class Test {
	 public static void main(String[] args) {
	        // 目标对象
	        IUserDao target = new UserDaoImp();
	        // 【原始的类型 class cn.itcast.b_dynamic.UserDao】
	        System.out.println(target.getClass());

	        // 给目标对象,创建代理对象
	        IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();
	        // class $Proxy0   内存中动态生成的代理对象
	        System.out.println(proxy.getClass());

	        // 执行方法   【代理对象】
	        proxy.playgame();
	    }
}

    3.3 Cglib代理(用于SpringAOP)

        ①无需抽象对象

        ②引入 Spring-core-3.2.0.RELEASE.jar 包

     目标对象

public class UserDaoImp{

	public void playgame() {
		 System.out.println("----已经保存数据!----");
	}

}

     代理工厂:

public class ProxyFactory implements MethodInterceptor{
    //维护目标对象
    private Object target;

    public ProxyFactory(Object target) {
        this.target = target;
    }

    //给目标对象创建一个代理对象
    public Object getProxyInstance(){
        //1.工具类
        Enhancer en = new Enhancer();
        //2.设置父类
        en.setSuperclass(target.getClass());
        //3.设置回调函数
        en.setCallback(this);
        //4.创建子类(代理对象)
        return en.create();

    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("开始事务...");

        //执行目标对象的方法
        Object returnValue = method.invoke(target, args);

        System.out.println("提交事务...");

        return returnValue;
    }
}

    测试类

public class Test {
	  
	public static void main(String[] args) {
	        //目标对象
		UserDaoImp target = new UserDaoImp();

	        //代理对象
		UserDaoImp proxy = (UserDaoImp)new ProxyFactory(target).getProxyInstance();

	        //执行代理对象的方法
	        proxy.playgame();
	    }
}

4.参考

https://www.cnblogs.com/cenyu/p/6289209.html

猜你喜欢

转载自blog.csdn.net/kunfd/article/details/79368081