什么是动态代理,JDK 动态代理和 CGLIB 代理 区别是什么
1.Spring框架中的动态代理是实现AOP(面向切面编程)的一种关键技术。代理就是通过代理类访问目标类之前,对目标类做增加(前置、后置处理),如日志记录、事务管理、安全检查等横切关注点。
2.JDK 动态代理需要依赖接口实现,代理处理类也要实现InvocationHandler接口,然后通过反射调用方法
3. CGLIB 代理可以直接对目标类进行增强,代理类要实现MethodInterceptor接口,需要传入目标类的class文件,通过字节码创建一个子类,在子类中调用父类方法进行拦截。
JDK动态代理的简单使用
//定义一个接口类
public interface Person {String getName();Integer getAet(); }
//定义一个实现类
public class Student implements Person{
@Override
public String getName() {
return "我是学生张三";
}
@Override
public Integer getAet() {
return 15;
}
}
//定义代理的处理类
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
@Slf4j
public class PersonJdkProxyHandle implements InvocationHandler {
private final Object target;
public PersonJdkProxyHandle(Object target) {
this.target = target;
}
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
try {
System.out.println("进入方法");
Object result = method.invoke(target, objects);
System.out.println("代理类执行完毕");
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
//定义方法测试
import java.lang.reflect.Proxy;
public class ProxyTest {
public static void main(String[] args) {
Person student = new Student();
Person studentProxy = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(),
new Class<?>[]{Person.class},
new PersonJdkProxyHandle(student)
);
String name = studentProxy.getName();
System.out.println(name);
}
}
cglib动态代理的简单使用
//定义一个代理类
public class Student implements Person {@Overridepublic String getName() {return "我是学生张三";}@Overridepublic Integer getAet() {return 15;} }
//定义一个代理处理类
public class CglibProxy implements MethodInterceptor {
private Enhancer enhancer = new Enhancer();
// 这里的目标类型为Object,则可以接受任意一种参数作为被代理类,实现了动态代理
public Object getInstance(Class clazz) {
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
// 返回代理对象
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("cglib动态代理开始");
Object result = methodProxy.invokeSuper(o,objects);
System.out.println("cglib动态代理结束");
return result;
}
}
//定义一个测试类
public class ProxyTest {
public static void main(String[] args) {
CglibProxy proxy = new CglibProxy();
Student student = (Student)proxy.getInstance(Student.class);
String name = student.getName();
System.out.println(name);
}
}
需要引入pom文件
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>