代理模式分为动态代理和静态代理
静态代理:
- 定义一个人类的接口:Person
- 实现类:Student
- 代理类:StuProxy 实现Person 在重写方法中调用Student,从而实现消息过滤,日志插入等AOP功能
动态代理:
- JDK动态代理
Student student = new Student();
Person person = (Person)Proxy.newProxyInstance(student.getClass().getClassLoader(), student.getClass().getInterfaces(), (proxy, method, params) -> {
System.out.println("做一个消息的过滤before");
method.invoke(student, params);
System.out.println("做一个消息的过滤after");
return null;
});
person.sayHello();
- 解释: java.lang.reflect.Proxy创建一个代理对象
参数分三个,第一个是classloader, 第二个接口数组,第三个是InvocationHandlerc增强invoke方法before, after可以写自己的需要的方法 - 特点:需要传入接口,newProxyInstance通过接口的反射拿到方法名等属性,在newProxyInstance定义中必须用接口模式,比较符合面向对象的思想
- 最终生成的代理类extend Proxy并实现了定义的传入的接口
- CGLIB动态代理
首先定义一个MyMethod自己的方法实现MethodInterceptor,增强intercept方法同理
static class MyMethod implements MethodInterceptor{
private Student stu;
public MyMethod(Student student){
stu = student;
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println(method);
System.out.println(objects.length);
System.out.println(methodProxy.getClass());
return methodProxy.invoke(stu, objects);
}
}
参数介绍:
- o 为对象
- method 调用的方法名
- objects为参数
- methodProxy:生成的代理对象的方法实例
method: public void com.firesoon.drgs.exe.test.Student.say()
objects为参数: [Ljava.lang.Object;@31b7dea0
methodProxy: class net.sf.cglib.proxy.MethodProxy
pom.xml文件
<!--cglib -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.4</version>
</dependency>
建议使用3.2.4 在3.2.6版本中new Enhancer()过程中出现包冲突的问题
然后在调用
public static void main(String[] args) {
Student student = new Student();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(student.getClass());
enhancer.setCallback(new MyMethod(student));
Student p = (Student)enhancer.create();
p.say();
}
- 根据实现类实现的代理的不需要传入接口
- 代理类对象是由Enhancer类创建的。Enhancer是CGLIB的字节码增强器
- superClass:实现类的class类生成二进制字节码文件,通过class对象反射出代理对象实例
- 在最后执行的时候执行的时候methodProxy.invoke();
网友评论