Spring Aop 代理
AOP 面向切面编程 底层就是 动态代理模式 代理模式是java中常用的设计模式。
特点为: 1 委托类和代理类有相同的接口,或共同的父类(保证使用一样的方法)
2 代理类为委托类负责处理消息,并将消息转发给委托类。
3 代理类并不是真正的实现者而是通过调用委托类的方法来实现功能。
代理 分为 静态代理和动态代理。
静态代理:
由程序员或者特定的工具自动生成了源代码,在程序运行之前 .class文件已经存在了。
静态代理实现时:需要一个接口和两个实现类(一个做目标对象,一个为代理对象)。
动态代理:在程序运行期间,通过反射的方法动态的创建出来的!
动态代理分为 GDK动态代理 和 Cglib动态代理。
GDK动态代理可以实现接口。
Cglib可以实现父类和接口。
静态代理
接口
public interface Subject { public void request(); }
实现类(目标对象)
public class RealSubject implements Subject { public void request() { System.out.println("okokok"); } }
实现类(代理对象)
public class ProxySubject implements Subject { public ProxySubject() { } private RealSubject realSubject;//目标对象 public void request() { System.out.println("write log"); realSubject.request(); } public RealSubject getRealSubject(RealSubject realSubject) { return this.realSubject; } public void setRealSubject(RealSubject realSubject) { this.realSubject = realSubject; } }
test
public class TestSubject { @Test public void t1(){ RealSubject realSubject=new RealSubject();//实例化目标对象 ProxySubject proxy=new ProxySubject();//实例化代理对象 proxy.setRealSubject(realSubject); //在代理对象中传入被 代理的目标对象 proxy.request(); } }
GDK动态代理 (实现接口)
接口
public interface IUserDao { public void addUser(); }
实现类
public class IUserDapimpl implements IUserDao { public void addUser() { System.out.println("添加成功111111111111111111111"); } }
test测试类 (在测试的时候 建立的代理类)
jdk的动态代理时需要知道 一个类Proxy 一个接口InvocationHandler(java.lang.reflect)
接口下只有一个方法
public Object invoke(object proxy ,Method method ,Object【】args );
object proxy 代理类 Method method 被代理的方法 Object【】args 被代理的方法的参数列表
Proxy 类
public static Object newProxyInstance(ClassLoader loder ,Class<?> [ ] interfaces ,InvocationHandler h ){
ClassLoader loder 类加载器 Class<?> [ ] interfaces 代理类实现的所有接口 h 接口的一个实例 ,this 当前对象 因为我们想使用jdk动态代理 必须是代理类实现 InvocationHandler 他让我们传递的是父接口 我们也可以穿自身 this
}
01.我们不确定代理类的类型 使用 Object
02. 给一个委托类返回一个代理对象‘
03 实现系统级业务和主业务的交互
public class MyTest {
public static void main(String[] args) { //jdk的动态代理 final IUserDapimpl dao=new IUserDapimpl();
//02. 给一个委托类返回一个代理对象‘ IUserDao log = (IUserDao) Proxy.newProxyInstance(dao.getClass().getClassLoader(), dao.getClass().getInterfaces(), new InvocationHandler() / this {
//03 实现系统级业务和主业务的交互 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("write log"); Object result = method.invoke(dao, args); return result; } }); //调用方法 log.addUser(); } }
Cglib动态代理 (实现接口 /继承 父类)
接口
public interface Animal { public void eat(); public void sleep(); }
委托类(dog 目标对象)
public class Dog implements Animal { public void eat() { System.out.println("狗狗吃饭"); } public void sleep() { System.out.println("狗狗睡觉"); } }
代理类 (CglibProxy)
Cglib 有也有一个类和一个接口
接口 MethodInterceptor 方法拦截器
MethodInterceptor implements callback { callback为空
Object intercept(Object obj ,Method method ,Object [ ]args ,MethodProxy proxy);
}
Enhancer类
设置委托类和代理类的公共的父类
public void setSupperClass(Class supperclass){
}
代理类执行完毕通知 委托类
public void setCallback(final CallBack callback){
set Callbacks (new Callback [ ] { callback / this })
}
在 Enhander类的父类 AbstractClassGraderatior 中有一个方法
创建我们需要的代理类
Protected Object create (Object key)
import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; /** * Enhancer 一个类 :创建我们需要的代理类 关联 代理类和委托类 * * MethodInterceptor:方法拦截器 是一个接口 * intercept 是所有拦截器的执行方法,类似于JDK动态代理的中的invoke */ public class CglibProxy implements MethodInterceptor { private Enhancer enhancer=new Enhancer(); //创建代理类对象 public Object createProxy(Class clazz){ enhancer.setSuperclass(clazz); enhancer.setCallback(this); return enhancer.create(); } public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("主人叫你"); Object result = methodProxy.invokeSuper(o, objects); System.out.println("主人离开"); return result; } }
test 测试类
public class Test { public static void main(String[] args) { CglibProxy cglibProxy=new CglibProxy(); Animal proxy = (Animal)cglibProxy.createProxy(new Dog().getClass()); proxy.eat(); proxy.sleep(); } }