AOP实现原理是基于动态代理实现的。
代理模式是一种软件设计模式。其核心思想是通过访问代理对象去操作被代理的对象。代理对象与被代理对象有同样的方法接口,且对被代理的对象的方法进行了扩展。从而实现不修改被代理对象的情况下,实现被代理对象业务逻辑的更改。
代理模式又分为静态代理和动态代理两种。
我的目录为:
一、静态代理是在代码编译是就确定了被代理对象。
实现方式:
1) 代理对象与被代理对象实现同样的接口==>保证行为一致与类型一致
2) 代理对象持有一个被代理对象。==>代理对象能够调用被代理对象的逻辑
a、Star.java文件
/** * 代理类与被代理类实现统一的接口 */ public interface Star { void actor(); void sing(); }
b、被代理对象LiuDenHua实现接口中的方法;
public class LiuDenHua implements Star{ @Override public void actor() { System.out.println("刘德华演戏"); } @Override public void sing() { System.out.println("刘德华唱歌"); } }
c、代理类去实现接口,并添加一些其他的业务方法;
/** * 代理类 */ public class StarProxy implements Star{ //持有一个被代理对象 private Star liuDenHua;//接口 //private LiuDenHua liuDenHua; public StarProxy(Star liuDenHua) { this.liuDenHua = liuDenHua; } @Override public void actor() { System.out.println("经纪人谈合同"); liuDenHua.actor(); System.out.println("经纪人收钱"); } @Override public void sing() { System.out.println("经纪人联系场地"); liuDenHua.sing(); System.out.println("经纪人收钱"); } }
d、写一个测试文件,测试是否成功;
public class Test { public static void main(String[] args) { //创建被代理对象 Star liuDenHua = new LiuDenHua(); //创建代理对象,并传入被代理对象 Star starProxy = new StarProxy(liuDenHua);
// starProxy.actor();
// starProxy.sing();
show(starProxy); }
public static void show(Star star){
star.actor();
star.sing();
}
}
测试结果为:
二、动态代理:在代码运行期间才加载被代理的类,动态生成代理对象。
Spring 动态代理有两种实现机制
1)JDK动态代理:jdk动态代理有java自身提供,其利用反射机制生成一个实现代理接口的匿名类(代理类)。Spring默认的方式。
a、 被代理的类需要实现接口。
b、接口
c、被代理类
d、生成代理对象的类 (实现InvocationHandler接口)
/** * 动态代理 * jdk代理 * 实现InvocationHandler */ public class JDKDynamicProxy implements InvocationHandler { //持有一个被代理对象 private Object object; /** * 根据被代理对象生成代理类 * @param targetObject 被代理的对象 * @return */ public Object getInstance(Object targetObject){ //给被代理对象赋值 this.object=targetObject; //生成代理对象 return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),//获取类加载器 targetObject.getClass().getInterfaces(),//获取被代理对象实现的接口 this//动态代理方法执行时,会调用该对象的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 invoke = method.invoke(object, args); System.out.println("提交事务"); return invoke; } }
测试:
public class Test { public static void main(String[] args) { //被代理类 LiuDenHua liuDenHua = new LiuDenHua(); JDKDynamicProxy jdkDynamicProxy = new JDKDynamicProxy(); //动态生成代理类对象 Star instance = (Star) jdkDynamicProxy.getInstance(liuDenHua); instance.sing(); instance.actor(); } }
2)cglib动态代理:通过java字节码编辑技术,生成一个被代理对象的一个子类(代理类)。来实现代理效果。
a. 被代理的类不需要实现接口
b. 被代理类(普通类)
c. 生成代理对象类(实现MethodInterceptor接口)
/** * cglib 动态代理 */ public class CglibDynamicProxy implements MethodInterceptor { /** * 生成代理对象的方法 * @param target * @return */ public Object getProxy(Object target){ return Enhancer.create(target.getClass(),this); } /** * * @param o 被代理的对象 * @param method 被代理的方法 * @param objects 方法参数 * @param methodProxy 代理方法 * @return * @throws Throwable */ @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("前置处理"); //调用被代理对象的方法 Object invoke = methodProxy.invokeSuper(o, objects); System.out.println("后置处理"); return null; } }
另外建一个Player.java文件:
/** * 普通类 */ public class Player { public void play(){ System.out.println("玩的很开心"); } }
测试:
//cglib动态代理 //创建被代理对象 Player player = new Player(); //创建生产动态代理对象的对象 CglibDynamicProxy cglibDynamicProxy = new CglibDynamicProxy(); //生产代理对象 Player proxy = (Player) cglibDynamicProxy.getProxy(player); proxy.play();