代理模式 提供了对目标对象另外的访问方式,及通过代理访问目标对象
这样的好处是 在实现目标对象的功能上,额外增强的功能操作。及代理对象是目标对象的
扩展实现
这里体现了编程的一个思想,别人写好的代码,不随意去修改,通过代理对象 对目标对象功能的扩展
代理模式的 关键点就是
目标对象和代理对象,代理对象是目标对象的扩展,同时调用目标对象
静态代理
/**
* @ClassName: 目标接口
* @Description: TODO
* @author wxtang
* @Date: 2019/4/17 9:20
* @version 1.0.0
*
*/
public interface Count {
void queryCount();
void updateCount();
}
/**
* @ClassName: 目标对象实现类
* @Description: TODO
* @author wxtang
* @Date: 2019/4/17 9:21
* @version 1.0.0
*
*/
public class CountImpl implements Count{
@Override
public void queryCount() {
System.out.println("查询账户。。。");
}
@Override
public void updateCount() {
System.out.println("修改账户。。。");
}
}
/**
* @ClassName: 静态代理
* @Description: TODO
* @author wxtang
* @Date: 2019/4/17 9:27
* @version 1.0.0
*
*/
public class CountProxy implements Count{
//接受保存目标对象
private Count count;
public CountProxy(Count count) {
this.count = count;
}
@Override
public void queryCount() {
System.out.println("查询账户预处理前。。。");
count.queryCount();
System.out.println("查询账户预处理后。。。");
}
@Override
public void updateCount() {
System.out.println("修改账户预处理前。。。");
count.updateCount();
System.out.println("修改账户预处理后。。。");
}
}
/**
* @ClassName: 静态代理测试类
* @Description: TODO
* @author wxtang
* @Date: 2019/4/17 9:15
* @version 1.0.0
*
*/
public class ProxyStaticTest {
public static void main(String[] args) {
Count count = new CountImpl();
CountProxy pro = new CountProxy(count);
//执行代理方法
pro.queryCount();
pro.updateCount();
}
}
静态代理可以再不修改目标对象的前提下,对目标对象的扩展
静态代理的缺点:
代理对象和目标对象都实现一个接口,类太多,当接口增加一个方法,目标对象和代理对象都需要需要维护,比较麻烦
对于静态代理的缺点 需要使用动态代理
动态代理
/**
* @ClassName: 目标接口
* @Description: TODO
* @author wxtang
* @Date: 2019/4/17 9:20
* @version 1.0.0
*
*/
public interface Count {
void queryCount();
void updateCount();
}
/**
* @ClassName: 动态代理
* @Description: TODO
* @author wxtang
* @Date: 2019/4/17 9:47
* @version 1.0.0
*
*/
public class DynameicProxy implements InvocationHandler{
private Object object;
public Object Buid(Object object) {
this.object = object;
return Proxy.newProxyInstance(object.getClass().getClassLoader(),object.getClass().getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("操作处理前。。。");
Object result = method.invoke(object, args);
System.out.println("操作处理后。。。");
return result;
}
}
/**
* @ClassName: 动态代理测试类
* @Description: TODO
* @author wxtang
* @Date: 2019/4/17 9:52
* @version 1.0.0
*
*/
public class ProxyDynamicTest {
public static void main(String[] args) {
Count count = new CountImpl();
DynameicProxy proxy = new DynameicProxy();
Count buid = (Count)proxy.Buid(count);
buid.queryCount();
buid.updateCount();
}
}
动态代理不需要实现接口 目标对象一定要实现接口,不然不能适用动态代理
CGLIB 动态代理
/**
* @ClassName: 目标类
* @Description: TODO
* @author wxtang
* @Date: 2019/4/17 10:07
* @version 1.0.0
*
*/
public class Counts {
public void queryCount(){
System.out.println("查询账户。。。");
}
public void updateCount(){
System.out.println("修改账户。。。");
}
}
/**
* @ClassName: cglib 动态代理类
* @Description: TODO
* @author wxtang
* @Date: 2019/4/17 10:08
* @version 1.0.0
*
*/
public class CglibProxy implements MethodInterceptor {
private Object object;
/*public CglibProxy(Object object) {
this.object = object;
}*/
//相当于JDK动态代理中的绑定
public Object getInstance(Object object) {
this.object = object; //给业务对象赋值
Enhancer enhancer = new Enhancer(); //创建加强器,用来创建动态代理类
enhancer.setSuperclass(this.object.getClass()); //为加强器指定要代理的业务类(即:为下面生成的代理类指定父类)
//设置回调:对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实现intercept()方法进行拦
enhancer.setCallback(this);
// 创建动态代理类对象并返回
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("操作处理前。。。");
//调用业务类(父类中的方法)
methodProxy.invokeSuper(o,objects);
System.out.println("操作处理后。。。");
return null;
}
}
/**
* @ClassName: Cglib 动态代理测试类
* @Description: TODO
* @author wxtang
* @Date: 2019/4/17 11:11
* @version 1.0.0
*
*/
public class CglibProxyTest {
public static void main(String[] args) {
Counts count = new Counts();
CglibProxy cglib = new CglibProxy();
Counts countCglib = (Counts)cglib.getInstance(count);
countCglib.queryCount();
countCglib.updateCount();
}
}