静态代理
- 静态代理需要代理对象和被代理对象都实现同一个接口或者父类
- 通过将接口或父类的实例(被代理对象)聚合到代理工厂的方式
- 在代理类中实现对被代理对象的方法调用
缺点:每个代理类只能代理一类对象,当需要代理多个类时,会需要写很多个代理工厂,这样代码扩展性不佳
public class StaticProxyTest {
public static void main(String[] args) {
Target target=new Target();
TargetProxyFactory proxyF=new TargetProxyFactory(target);
proxyF.method();
}
}
interface Infe{
void method();
}
class Target implements Infe{
@Override
public void method() {
System.out.println("我是目标对象");
}
}
class TargetProxyFactory implements Infe{
public Infe target;
public TargetProxyFactory(Infe target) {
this.target=target;
}
@Override
public void method() {
target.method();
}
}
利用反射机制实现动态代理
- 动态代理代理对象不需要实现接口,只需要被代理对象实现同一个接口
- 利用JDK中,java.lang.reflect.Proxy 的newProxyInstance()方法返回一个代理对象(被代理对象的接口实例)
public class AutoProxyTest {
public static void main(String[] args) {
AutoTarget target=new AutoTarget();
AutoProxyFactory factory=new AutoProxyFactory(target); //构造代理工厂时传入被代理的目标对象
Infe1 proxyInstance = (Infe1)factory.getProxyInstance();//获得代理对象
Object res=proxyInstance.method();//调用被代理对象的方法,接收返回值
//== int res=proxyInstance.method();
System.out.println(res);
}
}
//被代理对象实现的接口
interface Infe1{
int method();
}
//被代理对象
class AutoTarget implements Infe1{
@Override
public int method() {
System.out.println("我是目标对象");
return 666;
}
}
//代理工厂
class AutoProxyFactory {
public Object target;//传入所需被代理的对象
public AutoProxyFactory(Object target) {
//构造代理工厂时传入被代理的目标对象
this.target = target;
}
public Object getProxyInstance(){
//-----根据传入的被代理对象动态生成对应的代理对象
//1.ClassLoader :指定被代理对象的类加载器;
//2.Interface :指定被代理对象实现的接口;
//3.InvocationHandler :事件处理:执行目标方法时,会触发事情处理器方法,需要重写其invoke()方法
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//Object proxy:生成的代理对象
// Method method:被代理对象的方法
//Object[] args:被代理类调用的方法的参数
Object res= method.invoke(target,args);
return res;
}
});
}
}
cglib 动态代理
- 上一种动态代理的被代理对象必须有实现的接口,对于没有接口的类不可以使用该动态代理。
- cglib代理是利用创建被代理对象的子类来实现代理,所以当目标对象没有实现接口时,可以使用cglib代理。
但是cglib代理的目标对象不可以为final类,final类无继承类
步骤:
- 1.导入Cglib jar包
- 2.利用Enhancer工具类创建被代理对象(目标对象)的子类对象作为代理对象
- 3.重写 MethodInterceptor接口的intercept方法,实现对被代理对象的方法的调用
public class Target{
public void mmethod(){
System.out.println("目标对象");
}
}
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibProxy {
public static void main(String[] args) {
Target target=new Target();
Target proxy=(Target) Enhancer.create(target.getClass(), new MethodInterceptor(){
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object obj= method.invoke(target,args);
return obj;
}
});
proxy.mmethod();//执行代理对象的方法时会触发intercept方法
}
}