静态代理A类持有B类,同时实现了C接口,A类通过B类实现,前后增加自己的业务处理逻辑,从而实现对B类的代理。代码示例: 接口类C:
public interface C { public void printWork(); }实现类B:
public class B implements C { public void printWork() { System.out.println("打印工作"); } }代理类A:
public class A implements C { private C c; public A(C c){ this.c =c ; } public void printWork() { System.out.println("******插电启动*******"); c.printWork(); } public static void main(String[] args) { B b = new B(); b.printWork(); System.out.println("=======启动代理=========="); new A(b).printWork(); } }输出结果:
至此,我们已经简单完成了B类的代理类A.
动态代理是指在运行时动态生成代理类,而不需要我们每次指定代理对象和手写代理类,通过动态实现代理。
代理类需要实现InvocationHandler类。
java.lang.reflect.Proxy:这是 Java 动态代理机制的主类,由jdk提供,它提供了一组静态方法来为接口动态生成代理类及其对象。在我们上面静态代理中,类似A类的存在,根据接口生成新的实现类
java.lang.reflect.InvocationHandler:这是调用处理器接口,它自定义了一个 invoke 方法,用于集中处理在动态代理类对象上的方法调用,通常在该方法中实现对委托类的代理访问。
开始修改静态代理A类
创建AProxy类实现InvocationHandler接口invoke方法Proxy创建封装对象 import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class AProxy implements InvocationHandler{ private Object target; //传入需要代理的对象,对应B类引入,此处 //用Object封装 public AProxy(Object object){ this.target=object; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // to do something // 注意,此处使用我们传入的target,并非proxy System.out.println("******插电启动*******"); return method.invoke(target, args); } public Object creactProxyObject(){ return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } public static void main(String[] args) { B b = new B(); C c = (C) new AProxy(b).creactProxyObject(); c.printWork(); } }输出结果:
通过上述,我们可以到参数getInterfaces()方法,基于接口方式实现的动态代理。cglib通过继承来实现动态代理。
引入cglib的依赖,pom文件中增加
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.3.0</version> </dependency>创建普通类D:
public class D { public void sayHello(){ System.out.println("hello,i'm ok"); } }创建代理CglibProxy代理类:
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 CglibProxy implements MethodInterceptor{ // 根据一个类型产生代理类 public Object CreatProxyedObj(Class<?> clazz) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(clazz); enhancer.setCallback(this); return enhancer.create(); } public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { System.out.println("======插入前置通知======"); Object object = arg3.invokeSuper(arg0, arg2); System.out.println("======插入后者通知======"); return object; } public static void main(String[] args) { CglibProxy proxy = new CglibProxy(); D dd = (D) proxy.CreatProxyedObj(D.class); dd.sayHello(); }输入结果: 至此:完成了cglib基于继承方式实现的代理,在spring中,sping优先使用jdk动态代理,对于没有接口实现的类,采用cglib方式实现代理。