静态代理与动态代理

原文地址:https://blog.csdn.net/hon_3y/article/details/70655966

 

代理模式:提供了对目标对象另外的访问方式;即通过代理访问目标对象。 这样好处: 可以在目标对象实现的基础上,增强额外的功能操作。(扩展目标对象的功能)。

    简单来说,就是再创建一个代理,在代理类里面调用原有的目标对象,同时再做一些其他的处理,从而达到 不对目标对象修改的情况下 而可以扩充目标对象的功能。

静态代理

    

public class Deal {

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

        // 真正处理的 还是 target对象,所以需要传入
        IUserDao proxy = new UserDaoProxy(target);
        proxy.save();  // 执行的是,代理的方法

	}

}

/**
 * 声明一个接口
 * @author Administrator
 *
 */
interface IUserDao {
    void save();
}

/**
 * userDao实现该接口 并重写save方法
 * @author Administrator
 *
 */
class UserDao implements IUserDao{

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

}


/**
 * 声明一个代理类,该代理类对原有的类的方法做了扩充处理   :前后添加了事务处理
 * @author Administrator
 *
 */
class UserDaoProxy implements IUserDao{

    // 接收保存目标对象【真正做事的还是UserDao】,因此需要维护userDao的引用
    private IUserDao target;
    public UserDaoProxy(IUserDao target) {
        this.target = target;
    }

    @Override
    public void save() {
        System.out.println("开始事务...");

        target.save();          // 执行目标对象的方法

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

}

以上代码实现的就是静态代理,代理类在原有的类的方法里面 添加了一些特殊的处理。

优点:实现与目标类的解耦,不需要修改目标类,可以实现添加的功能。

缺点:以后每个类 都要写一个代理类,并且实现同样的接口。接口要是变化,所有都要变化,而且类也很多。

 

解决办法:动态代理

 

动态代理:代理类在程序运行时创建的

动态代理比静态代理好的地方:

  • 代理对象,不需要实现接口【就不会有太多的代理类了】
  • 代理对象的生成,是利用JDK中的Reflection包中的Api, 动态地在内存中构建代理对象(需要我们指定创建 代理对象/目标对象 实现的接口的类型;)

代码演示

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class MyProxy {

	public static void main(String[] args) {
		// 代理的真实对象
		UserServiceImpl realSubject = new UserServiceImpl();
		/**
		 * InvocationHandlerImpl 实现了 InvocationHandler 接口,并能实现方法调用从代理类到委托类的分派转发
		 * 其内部通常包含指向委托类实例的引用,用于真正执行分派转发过来的方法调用.
		 * 即:要代理哪个真实对象,就将该对象传进去,最后是通过该真实对象来调用其方法
		 */
		InvocationHandler handler = new MyInvocationHandler(realSubject);

		ClassLoader loader = handler.getClass().getClassLoader();
		Class<?>[] interfaces = realSubject.getClass().getInterfaces();
		/**
		 * 该方法用于为指定类装载器、一组接口及调用处理器生成动态代理类实例
		 */
		UserServiceImpl subject = (UserServiceImpl) Proxy.newProxyInstance(
				loader, interfaces, handler);

		System.out.println("动态代理对象的类型:" + subject.getClass().getName());

		subject.query();

      
       UserService service = MyInvacationHandler.createProxy(new UserserviceImpl);
       service.query();
	}

}

/**
 * 定义一个接口
 * @author Administrator
 *
 */
interface UserService {
	void query();
}

/**
 * 接口的实现类
 * @author Administrator
 *
 */
class UserServiceImpl implements UserService {
	public void query() {
		System.out.println("查询用户信息");
	}
}


public class MyInvacationHandler implements InvocationHandler {
    
	//代理对象
	private Object targetObject;
	
    public MyInvacationHandler(Object targetObject) {
    	
    	this.targetObject = targetObject;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("开始事务");
		Object result =method.invoke(targetObject, args);
		System.out.println("结束事务");
		return result;
	}
	
	/**
	 * 创建代理对象
	 * @param target   被代理对象
	 * @param 
	 * @return
	 */
	public static <T> T createProxy(Object target) {
		
        return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),
        		target.getClass().getInterfaces(), new MyInvacationHandler(target));
		
	}

}

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值