springAOP总结(就是两个字代理)
- AOP面向切面编程,原理就是代理,代理类对被代理类代码的增强。
- 静态代理,就是两个类实现同一个类的接口重写接口里面的方法,一个类写具体的业务代码,另一个类只写增强代码,并调用另一个类的方法,来实现代码的增强。缺点就是,代码复杂,针对每一个被代理的类都要重新创建一个代理类,这就导致代码量增多,同时重复的代码也会增多(可复用性差),可维护性也比较差。
- 动态代理,分两种:
3.1)jdk动态代理
Jdk中提供了Proxy类,用于动态的创建代理对象
public class A implements AInterface {
public int add(int x, int y) {
System.out.println("结果为:" + (x + y));
return x + y;
}
public int minus(int x, int y) {
System.out.println("结果为:" + (x - y));
return x - y;
}
}
public class JDKProxy implements InvocationHandler {
//目标代理对象(被代理的对象)
private Object target;
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
public Object getProxy(){
/**
* newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
* loader - 定义代理类的类加载器
* interfaces - 代理类要实现的接口列表
* h - 指派方法调用的调用处理程序
*/
return Proxy.newProxyInstance(
this.target.getClass().getClassLoader(),
this.target.getClass().getInterfaces(),
this);
}
/**
* invoke表示代理对象在执行方法时所调用的真正的方法,也可以理解为代理对象调用方法的回调函数
* 代理实例上的方法调用将被指派到实例的调用处理程序的 Invoke 方法
* @param proxy
* @param method
* @param args
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[]args ) throws Throwable {
//调用处理程序
//既包含增强代码,也包含对代理对象的方法的调用
System.out.println("程序开始执行");
Object o = method.invoke(this.target,args);
System.out.println("程序结束执行");
return o;
}
}
A a = new A();
JDKProxy jdkProxy = new JDKProxy();
jdkProxy.setTarget(a);
//返回的Object对象就是产生的代理对象
Object o = jdkProxy.getProxy();
//代理对象是通过接口产生,即意味着,只能通过接口对象接收(强转)
AInterface a1 = (AInterface)o;
a1.add(2, 3);
a1.minus(4, 2);
注意:jdk的proxy产生代理对象的方式,要求,被代理的类必须有实现的接口,同时返回的代理对象也只能使用接口对象接收(强转)。
当被代理的类没有接口时,jdk的Proxy无法使用,要解决需使用下面的Cglib库。
3.2)CGLIB动态代理
引入依赖
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
创建代理类及拦截类
public class CGProxy implements MethodInterceptor {
public Object getProxy(Class clazz){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(clazz);
//创建的代理对象设置回调对象,回调对象即拦截的对象执行其拦截方法(intercept方法)
//代理的实例的方法执行时,被callback对象拦截,从而执行拦截器中intercept方法
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("cg代理程序开始执行");
Object o1 = methodProxy.invokeSuper(o,objects);
System.out.println("cg代理程序结束执行");
return o1;
}
}