静态代理:
优点:
可完成在不修改目标对象的功能前提下,对目标功能扩展.
缺点:
1. 都要实现公共接口
2. 需要创建一个代理类,并且只能代理一个对象
用例:
package designPattern.proxy;
/**
* @Author Snail
* @Describe
* @CreateTime 2019/6/29
*/
public class TestStaticProxy {
public static void main(String[] args) {
Static aStatic = new Static();
//代理对象,把目标对象传给代理对象,建立代理关系
StaticProxy proxy = new StaticProxy(aStatic);
proxy.save();//执行的是代理的方法
}
}
//接口
interface IStatic {
void save();
}
//目标对象
class Static implements IStatic {
public void save() {
System.out.println("----已经保存数据!----");
}
}
//静态代理对象
class StaticProxy implements IStatic{
//接收保存目标对象
private Static target;
public StaticProxy(Static target){
this.target=target;
}
public void save() {
System.out.println("开始事务...");
target.save();//执行目标对象的方法
System.out.println("提交事务...");
}
}
JDK动态代理:
目标对象必须有接口,且创建的代理对象也是需要转化成接口类型去执行方法,这个过程制作快,执行慢
package designPattern.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @Author Snail
* @Describe
* @CreateTime 2019/6/29
*/
public class TestDynamicProxy {
public static void main(String[] args) {
//目标对象
final Dynamic target = new Dynamic();
//动态创建代理对象
IDynamic proxy = (IDynamic) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
//被执行几次?------- 看代理对象调用方法几次
//代理对象调用接口相应方法 都是调用invoke
/*
* proxy:是代理对象
* method:代表的是目标方法的字节码对象
* args:代表是调用目标方法时参数
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开始事务...");
//反射知识点
Object invoke = method.invoke(target, args);//目标对象的相应方法
System.out.println("提交事务...");
//retrun返回的值给代理对象
return invoke;
}
}
);
proxy.save();//调用invoke---Method:目标对象的method1方法 args:null 返回值null
String retMethod = proxy.retMethod("动态代理 ");////调用invoke-----Method:目标对象的retMethod方法 args:Object[]{} 返回值
System.out.println(retMethod);
}
}
/**
* 公共接口
*/
interface IDynamic{
void save();
String retMethod(String str);
}
/**
* 目标对象
*/
class Dynamic implements IDynamic{
@Override
public void save() {
System.out.println("保存數據。。。。。");
}
@Override
public String retMethod(String str) {
return str+"目标对象";
}
}
CGlib动态代理:
以 继承 来实现,主要解决没有接口类的代理实现。 这个过程制作慢,执行快。
public class TestCGlibProxy {
public static void main(String[] args) {
CGlibProxyFactory factory = new CGlibProxyFactory();
CGlib cGlib = (CGlib) factory.getProxyInstance(new CGlib());
String str=cGlib.retMethod("Tom");
System.out.println(str);
}
}
class CGlibProxyFactory implements MethodInterceptor {
private Object targetObject;
//给目标对象创建一个代理对象
public Object getProxyInstance(Object targetObject){
this.targetObject = targetObject;
//1.工具类
Enhancer enhancer = new Enhancer();
//2.设置父类
enhancer.setSuperclass(this.targetObject.getClass());
//3.设置回调函数
enhancer.setCallback(this);
//4.创建子类(代理对象)
return enhancer.create();
}
/**
* 当代理对象的方法被调用时会调用该方法
* @param proxy 带来的对象本身
* @param method 被拦截到的方法
* @param objects 方法的参数
* @param methodProxy 方法的代理对象
*/
@Override
public Object intercept(Object proxy, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
Object ret = null;
try {
System.out.println("sout in cglib proxy ::::before");
ret = method.invoke(this.targetObject, objects);
System.out.println("sout in cglib proxy ::::after");
} catch (Exception e){
e.printStackTrace();
}
return ret;
}
}
//目标对象 该类由于是使用继承原理实现的,所以类不能用final修饰,类中属性可以
class CGlib{
public String retMethod(String tom) {
System.out.println("sout in cglib ");
return "sout in cglib :"+tom ;
}
}