1.在写这篇文章之前,我先问了一下自己,为什么要用到代理,首先最想想到的AOP,对这个应该熟悉的不能再熟悉,spirng的面向切面编程,springboot 中全局异常拦截,spirngboot 中事物处理,springboot实现统一日志拦截。也就是说,把共性的东西抽离出来,这样不影响原来的代码逻辑。springboot @Aspect 中很重要的三种拦截(方法执行之前,方法执行中,方法执行后),springboot 中实现代理可以有俩种方式 默认java自带的代理Proxy以及可以配置使用cglib代理。代理可以分为俩种静态代理,动态代理。
2.静态代理,用自己的话来说就是,代理对象和当前需要代理的对象实现同一个接口,而代理的对象中持有一个需要代理对象,这样在方法的执行前后都可以对方法进行拦截,撸一下具体实现的代码
public interface Person {
void execute();
}
public class Student implements Person{
@Override
public void execute() {
System.out.println("我是学生类的实例");
}
}
public class StudentProxy implements Person{
private Student student;
public StudentProxy(Student student){
this.student = student;
}
@Override
public void execute() {
System.out.println("拦截方法之前");
student.execute();
System.out.println("拦截方法之后");
}
public static void main(String[] args) {
Student student = new Student();
StudentProxy studentProxy = new StudentProxy(student);
studentProxy.execute();
}
}
3.动态代理类:在运行时间创建代理对象,而这也是和静态代理不同的地方,静态代理代理对象在刚创建的时候就需要实现跟代理对象一样的方法,所以在修改被代理的对象的同时需要修改代理对象,撸一下代码
public class MyInvocationHandler implements InvocationHandler {
//要代理的真实对象
private Object subject;
public MyInvocationHandler(Object subject){
this.subject = subject;
}
//当代理的方法被调用时,代理会把这个调用转发给InvocationHandler。
//不管代理被调用的事何种方法,处理器被调用的一定是invoke方法。
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//在调用真实对象方法前我们可以添加一些自己的操作
System.out.println("before rent house");
System.out.println("Method:" + method);
//通过Method类调用真实对象的方法
method.invoke(subject, args);
//在调用真实对象方法后我们也可以添加一些自己的操作
System.out.println("after rent house");
return null;
}
public static void main(String[] args) {
Person person = new Student();
InvocationHandler handler = new MyInvocationHandler(person);
Person proxy = (Person)Proxy.newProxyInstance(person.getClass().getClassLoader(),
person.getClass().getInterfaces(),handler);
proxy.execute();
}
}
动态代理对象最主要的有俩个,首先我们需要实现InvocationHandler 接口 实现invoke方法,动态代理利用的是java 反射机制,然后需要用Proxy中newProxyInstance 方法获取到需要代理对象。