代理模式的概念:
代理模式是对象的结构模式。代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用,以控制对这个对象的访问。 代理类和委托类有共同的父类或父接口,这样在任何使用委托类对象的地方都可以用代理对象替代。代理类负责请求的预处理、过滤、将请求分派给委托类处理、以及委托类执行完请求后的后续处理。
1.静态代理:
由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是代理类和委托类的关系在运行前就确定了,在程序运行前就已经存在代理类的字节码文件(class文件)。
2.
1)JDK动态代理:
动态代理类是在程序运行期间由JVM根据反射等机制动态的生成。代理类和委托类的关系是在程序运行时确定的,所以其字节码文件是动态生成的。
注:JDK动态代理只能代理实现了接口的类,而没有实现接口的类就不能用JDK的动态代理
2)cgllib动态代理:
针对类来实现代理的,他的原理是采用的是继承的方式,对指定的目标类生成一个子类,并覆盖其中方法实现增强;但因为采用的是继承,所以不能对final修饰的类进行代理。
3. 静态&动态代理 例子如下:(建议先看接口1相关的内容,进阶再结合接口2)
package com.founder.rcp.controller;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class TestProxy {
public static void main(String[] args) {
//静态代理1:调用静态代理类工厂
Subject sub1= StaticProxyFactory.getInstance();
sub1.opearate();
sub1.op2();
//静态代理2
Subject2 sub2 = StaticProxyFactory.getInstance2();
sub2.op3();
//动态代理1
Subject dynProxyIns = DynProxyFactory.newProxyInstance();
dynProxyIns.opearate();
dynProxyIns.op2();
//动态代理2
Subject2 dyn2 = DynProxyFactory.newProxyInstance2();
dyn2.op3();
//静态代理VS动态代理总结:
//1. 静态代理,有两个接口就得写两个代理类,扩展性差;而动态代理1和动态代理2 可以共用一个SubjectInvocationHandler,减少了类的数量;
//2.当接口中有多个方法,静态代理需要每个方法都进行中转;而动态代理可以把接口中所有的方法转移到SubjectInvocationHandler(调用处理器)的一个集中方法(invoke)处理,
//实际应用中可以用spring AOP把外围业务抽离出来(即invoke方法中不嵌入具体的外围业务),起到解耦合的作用。
}
}
/**
* 动态代理类对应的调用处理类
* @author li_yuhua
*
*/
class SubjectInvocationHandler implements InvocationHandler{//<span style="font-family: Arial, Helvetica, sans-serif;">InvocationHandler: JDK中的调用处理器通用接口,<span style="font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 25.2000007629395px;">它自定义了一个 invoke 方法,用于集中处理在动态代理类对象上的方法调用,通常在该方法中实现对委托类的代理访问。每次生成动态代理类对象时都要指定一个对应的调用处理器对象。 </span></span>
//委托类
Object sub;
public SubjectInvocationHandler(Object subject){
this.sub = subject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("动态预处理。。。。");
//利用反射将请求分派给为委托类执行
method.invoke(sub, args);
System.out.println("动态后处理。。。。");
return null;
}
}
/**
* 生成动态代理类的工厂类
* @author li_yuhua
*
*/
class DynProxyFactory{
public static Subject newProxyInstance(){
Subject realSub = new RealSubject();
//InvocationHandler:调用处理器接口
InvocationHandler subInvoHandler = new SubjectInvocationHandler(realSub);
Subject dynProxy = null;
//Proxy:所有动态代理类的父类<span style="font-family: Arial, Helvetica, sans-serif;">,</span><span style="font-family: Arial, Helvetica, sans-serif;">它提供了一组静态方法来为一组接口动态地生成代理类及其对象</span>
dynProxy = (Subject)Proxy.newProxyInstance(realSub.getClass().getClassLoader(), realSub.getClass().getInterfaces(), subInvoHandler);
return dynProxy;
}
public static Subject2 newProxyInstance2(){
Subject2 realSub2 = new RealSubject2();
//InvocationHandler:调用处理器接口
InvocationHandler subInvoHandler = new SubjectInvocationHandler(realSub2);
Subject2 dynProxy = null;
dynProxy = (Subject2)Proxy.newProxyInstance(realSub2.getClass().getClassLoader(), realSub2.getClass().getInterfaces(), subInvoHandler);
return dynProxy;
}
}
interface Subject{
public void opearate();
public void op2();
}
interface Subject2{public void op3();}
/**
* 委托类
* @author li_yuhua
*
*/
class RealSubject implements Subject{
@Override
public void opearate() {
// TODO Auto-generated method stub
}
@Override
public void op2() {
// TODO Auto-generated method stub
}}
/**
* 委托类2:实现了接口2
* @author li_yuhua
*
*/
class RealSubject2 implements Subject2{
@Override
public void op3() {
// TODO Auto-generated method stub
}
}
/**
* 静态代理类1
* @author li_yuhua
*
*/
class ProxySubject implements Subject{
RealSubject real = new RealSubject();
@Override
public void opearate() {
// TODO Auto-generated method stub
System.out.println("预处理方法1");
real.opearate();
System.out.println("后处理方法1");
}
@Override
public void op2() {
System.out.println("预处理方法2");
real.op2();
System.out.println("后处理方法2");
}
}
/**
* 静态代理类2
*/
class ProxySubject2 implements Subject2{
Subject2 real = new RealSubject2();
@Override
public void op3() {
System.out.println("预处理方法3");
real.op3();
System.out.println("后处理方法3");
}
}
/**
* 静态代理工厂类
*/
class StaticProxyFactory{
public static Subject getInstance(){
return new ProxySubject();
}
public static Subject2 getInstance2(){
return new ProxySubject2();
}
}
输出结果:
预处理方法1
后处理方法1
预处理方法2
后处理方法2
预处理方法3
后处理方法3
动态预处理。。。。
动态后处理。。。。
动态预处理。。。。
动态后处理。。。。
动态预处理。。。。
动态后处理。。。。
4. Cglib动态代理 例子如下:
package com.founder.rcp.controller;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class TestCGLib {
public static void main(String[] args) {
CglibProxy cglib = new CglibProxy();
//cglib:通过生成子类的方式创建代理类
Consigner con = (Consigner)cglib.getProxy(new Consigner());
con.opearate();
}
}
/**
* 代理类
*/
class CglibProxy implements MethodInterceptor{
//委托类成员声明
private Object target;
//创建代理对象
public Object getProxy(Object target){
this.target = target;
Enhancer hancer = new Enhancer();//增强者
//设置代理类的父类(target)
hancer.setSuperclass(this.target.getClass());
hancer.setCallback(this);
//创建代理对象:通过字节码技术动态创建实例
Object agent =hancer.create();
return agent;
}
//实现MethodInterceptor接口方法
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println("预处理,事务等。。。");
//通过代理类调用父类中的方法
proxy.invokeSuper(obj, args);
System.out.println("后处理,事务等。。。");
return null;
}
}
/**
* 委托类
* @author li_yuhua
*
*/
class Consigner{
public void opearate(){System.out.println("方法中");};
}
输出结果:
预处理,事务等。。。
方法中
后处理,事务等。。。