卧槽,突然发现自己没有代理这个概念。赶紧写篇博客记一下。
1.什么是代理模式?
静态代理
代理类由我们自己创建
继承实现代理
简单的讲A类,被B类重写方法后,我们通过调用B类方法,间接调用A类方法,像这样,我们不用直接操作A类调用echo()方法啊,而是通过重写间接调用echo(),B类方法本身没有实际功能(也可以丰富A的功能),只是为了调用A类。
这样我们称B类为A类的代理对象。
坏处:
class A {
public void echo() {
System.out.println("a--------");
}
public static void main(String[] args) {
// 通过B a(),间接调用A A()
new B().echo();
}
}
class B extends A {
@Override
public void echo() {
System.out.println("执行-------------");
super.echo();
}
}
组合实现代理
代理类和被代理类同时实现一个接口,创建代理类实例对象时,将被代理类的实例对象当做参数传进去。(接口,起一个规范约束作用)
好处:看的出来,我们要想代理其他被代理类,那么创建时实现该接口即可。
JDK动态代理就是采用的这种方式实现的。同样的代理类是由JDK自动帮我们在内存生成的。
public class Tank implements Movable{
@Override
public void move() {
System.out.println("Tank moving cla....");
}
public static void main(String[] args) {
Tank tank = new Tank();
new LogProxy(tank).move();
}
}
class LogProxy implements Movable{
private Movable movable;
public LogProxy(Movable movable) {
this.movable = movable;
}
@Override
public void move() {
System.out.println("方法执行前....");
movable.move();
System.out.println("方法执行后....");
}
}
interface Movable {
void move();
}
动态代理
代理类根据我们的提示生成。
怎么说呢?
1.jdk反射代理
我们需要自定义一个接口,jdk反射根据我们定义接口来实现代理生成所实现的接口。
interface Movable {
void move();
}
class Tank implements Movable {
@Override
public void move() {
System.out.println("Tank .........");
}
public static void main(String[] args) {
Tank tank = new Tank();
//newProxyInstance: 创建代理对象
// 参数一: 被代理类对象
// 参数二:接口类对象 被代理对象所实现的接口
// 参数三:调用处理器。 被调用对象的那个方法被调用后该如何处理
Movable o = (Movable) Proxy.newProxyInstance(Tank.class.getClassLoader(), new Class[]{Movable.class}, new LogProxy(tank));
o.move();
}
}
class LogProxy implements InvocationHandler {
private Movable movable;
public LogProxy(Movable movable) {
this.movable = movable;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("方法:" + method.getName() + "()执行前");
// args,
Object invoke = method.invoke(movable, args); // 此处相当于 movable.move()
System.out.println("方法:" + method.getName() + "()执行后");
return invoke;
}
}
// 可以这样想,本质上就是一个组合静态代理,只不过代理对象,由jdk来创建
// 这个是封装逻辑用的,我们创建一个代理对象,
// jdk创建的代理对象,也去实现我们定义的接口,那么让他如何去找到并去实现,并找到代理对象,并丰富功能的呢?答案:我自己传给他的。
//newProxyInstance(被代理对象.getClassLoder(),new Class[]{规范接口类},new 封装功能),而你看 封装逻辑用的Invoke方法,是不是很眼熟?不是反射调用吗?method参数不就是你想丰富功能的方法反射吗.movale 一开始我们newProxy..代理对象是就已经将对象传进去了,而你再看args是不是很容易想到,你调用代理对象要传入的参数呢?
Proxy,自然就是jdk为我们创还能的代理对象了。
2.SpringAOP原理讲解。
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("app_auto.xml");
Object o = context.getBean("tank");
String name = o.getClass().getName();
String superName = o.getClass().getSuperclass().getName();
System.out.printlf(name);
System.out.println(superName);
}
}
看的出,经过代理之后的对象有父类,这证明是继承代理来实现的。