原文地址: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));
}
}