Spring的AOP核心采用的设计模式采用的是代理模式,先介绍下Java的代理。
这里借鉴一下其他人的介绍,https://blog.csdn.net/fighterandknight/article/details/51200470
一 代理模式
代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。
1.静态代理
先定义接口是实现类:
public interface Test{ public void test(); }
public class TestImpl implements Test{ @Override public void test() { System.out.println("测试方法..."); } }
添加代理类:
1 public class TestProxy implements Test{ 2 private TestImpl testImpl; 3 4 /** 5 * 覆盖默认构造器 6 * 7 * 8 */ 9 public TestProxy (TestImpl testImpl) { 10 this.testImpl= testImpl; 11 } 12 13 @Override 14 public void test() { 15 System.out.println("事务处理之前"); 16 // 调用委托类的方法; 17 testImpl.test(); 18 System.out.println("事务处理之后"); 19 } 20 } 21
测试类:
1 public class TestCount { 2 public static void main(String[] args) { 3 TestImpl testImpl = new TestImpl (); 4 TestProxy testProxy = new TestProxy (testImpl ); 5 testProxy.test(); 6 7 } 8 }
2.Jdk动态代理
只能对实现了接口的类生产代理,不能针对类。
定义代理:
1 public class MyInvocationHandler implements InvocationHandler { 2 3 4 //目标对象 5 private Object target; 6 7 /** 8 * 构造方法 9 * @param target 目标对象 10 */ 11 public MyInvocationHandler(Object target) { 12 super(); 13 this.target=target; 14 } 15 16 * 执行目标对象的方法 17 */ 18 public Object invoke(Object proxy, Method method, Object[] args) 19 throws Throwable { 20 21 //在目标方法执行前简单打印一下 22 System.out.println("----------before----------"); 23 24 //执行目标方法对象 25 Object result=method.invoke(target, args); 26 27 //在目标方法执行之后简单打印一下 28 System.out.println("----------after----------"); 29 30 return result; 31 } 32 33 34 /** 35 * 获取目标对象的代理对象 36 * @return 代理对象 37 */ 38 public Object getProxy(){ 39 return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), 40 this.target.getClass().getInterfaces(),this); 41 } 42 43 }
测试类:
1 public class ProxyTest{ 2 3 @Test 4 public void testProxy() throws Throwable{ 5 //实例化目标对象 6 Test test=new TestImpl(); 7 8 //实例化Invocation 9 MyInvocationHandler invocationHandler=new MyInvocationHandler(test); 10 11 //根据目标生成代理对象 12 Test proxy=(Test)invocationHandler.getProxy(); 13 14 //调用代理对象方法 15 proxy.test(); 16 } 17 }
3.cglib代理
cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法,因为采用的是继承,所以不能对final修饰的类进行代理。
定义代理:
1 public class CglibProxy implements MethodInterceptor { 2 private Object target; 3 4 /** 5 * 创建代理对象 6 * 7 * @param target 8 * @return 9 */ 10 public Object getInstance(Object target) { 11 this.target = target; 12 Enhancer enhancer = new Enhancer(); 13 enhancer.setSuperclass(this.target.getClass()); 14 // 回调方法 15 enhancer.setCallback(this); 16 // 创建代理对象 17 return enhancer.create(); 18 } 19 20 @Override 21 // 回调方法 22 public Object intercept(Object obj, Method method, Object[] args, 23 MethodProxy proxy) throws Throwable { 24 System.out.println("事物开始"); 25 proxy.invokeSuper(obj, args); 26 System.out.println("事物结束"); 27 return null; 28 29 30 } 31 32 }
测试类:
public class TestCglib { public static void main(String[] args) { CglibProxy cglib=new CglibProxy (); Testmpl testImpl=(Testmpl)cglib.getInstance(new Testmpl()); testImpl.test(); }
二 Spring Aop
AOP利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。
使用"横切"技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处基本相似,比如权限认证、日志、事物。
Aop中的几个概念:
切面(Aspect) :官方的抽象定义为“一个关注点的模块化,这个关注点可能会横切多个对象”。
连接点(Joinpoint) :程序执行过程中的某一行为。
通知(Advice) :“切面”对于某个“连接点”所产生的动作。
切入点(Pointcut) :匹配连接点的断言,在AOP中通知和一个切入点表达式关联。
目标对象(Target Object) :被一个或者多个切面所通知的对象。
AOP代理(AOP Proxy) 在Spring AOP中有两种代理方式,JDK动态代理和CGLIB代理。
作用:
1、降低模块之间的耦合度
2、使系统容易扩展
3、更好的代码复用。
源码太多,就不一一列举了,源码分析可以参考:https://blog.csdn.net/hello_worldee/article/details/78136616
原文地址:https://www.cnblogs.com/jameszheng/p/10256680.html