概念理解
代理是一种软件设计模式,目的地希望能做到代码重用。代理这种设计模式是通过不直接访问被代理对象的方式,而访问被代理对象的方法。这个就好比 商户---->明星经纪人(代理)---->明星这种模式。我们可以不通过直接与明星对话的情况下,而通过明星经纪人(代理)与其产生间接对话,JAVA中的代理分为两种。
静态代理类:由程序员创建或由特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
动态代理类:在程序运行时,运用反射机制动态创建而成。
实现方式
动态代理的实现方式有两种第一种JDK自带的,缺点代理委托类必须是实现接口方法,具有致命的局限性,而第二种CgLib则屏蔽了这个局限性,可以代理任意委托类的方法,但是Cglib代理实现,借助了ASM字节码生成框架编写继承我们委托类的代理类字节码,所以如果委托类被修饰为 final,那CGLIB 代理不了。
实体类:student对象
/**
* @author shengtao
* @Description:
* @date 2019/04/11 9:56
*/
public class Student {
public Student(String name, int age) {
this.name = name;
this.age = age;
}
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) throws IOException{
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
JDK代理类示例:
接口类:IStudentService
/**
* @author shengtao
* @Description:
* @date 2019/04/11 12:36
*/
public interface IStudentService {
Student createStudent(String name ,int age);
}
IStudentService接口的实现类:StudentServiceImpl
public class StudentServiceImpl implements IStudentService {
@Override
public Student createStudent(String name ,int age) {
Student student = new Student("lishengtao",32);
return student;
}
}
实现了InvokationHandler的代理对象:DynamicProxy
/**
* @author shengtao
* @Description:
* @date 2019/04/11 12:40
*/
public class DynamicProxy implements InvocationHandler {
private Object target;
public DynamicProxy(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("执行开始");
Object obj = method.invoke(target,args);
System.out.println("执行结束");
return obj;
}
}
JDK动态代理测试类:DynamicTest
/**
* @author shengtao
* @Description:
* @date 2019/04/11 12:42
*/
public class DynamicTest {
public static void main(String[] args){
IStudentService studentService = new StudentServiceImpl();
InvocationHandler invocationHandler = new DynamicProxy(studentService);
IStudentService proxy = (IStudentService) Proxy.newProxyInstance(studentService.getClass().getClassLoader(),studentService.getClass().getInterfaces(),invocationHandler);
Student student = proxy.createStudent("李胜涛",22);
System.out.println(ToStringBuilder.reflectionToString(student));
}
}
运行结果:
执行开始
执行结束
com.lesent.model.reflection.Student@77cd7a0[name=lishengtao,age=32]
CgLib实现动态代理示例
编写代码前引入Cglib的依赖:pom.xml添加
<!-- https://mvnrepository.com/artifact/cglib/cglib -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.10</version>
</dependency>
被代理对象及方法实现:StudentServiceImpl2
public class StudentServiceImpl2 {
public Student createStudent(String name ,int age) {
Student student = new Student("lishengtao",32);
return student;
}
}
代理方法接口实现:InterCeptorHandler
class InterCeptorHandler implements MethodInterceptor{
public Object getProxy(Class<?> clazz){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(clazz);
//设置回调方法
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//切记不要使用 method.invoke(o,objects) 和 methodProxy.invoke(o, args); 否则会死循环
System.out.println("执行开始");
Object o1 = methodProxy.invokeSuper(o,objects);
System.out.println("执行结束");
return o1;
}
}
代理测试类:DynamicProxy
/**
* @author shengtao
* @Description:
* @date 2019/04/11 13:19
*/
public class DynamicProxy {
public static void main(String[] args){
InterCeptorHandler interCeptorHandler = new InterCeptorHandler();
StudentServiceImpl2 studentServiceImpl2 = (StudentServiceImpl2) interCeptorHandler.getProxy(StudentServiceImpl2.class);
Student student = studentServiceImpl2.createStudent("李胜涛",22);
System.out.println(ToStringBuilder.reflectionToString(student));
}
}