SpringAOP基础知识储备

1.连接点(Joinpoint)
  程序执行的某个特定位置:如类开始初始化前,类初始化后,类某个方法调用前,调用后,方法跑出异常后。一个类或一段程序代码拥有一些具有边界性质的特定点、这些代码中的特定点就成为连接点。
Spring仅支持方法的连接点,即仅能在方法调动前,方法调用后,方法跑出异常时以及方法调用前后这些程序执行点织入增强。
连接点由两个信息确定:
  1)方法表示程序执行点
  2)用相对点表示的方位。
如在Test.foo()方法执行前的连接点,执行点为Test.foo(),方位为该方法执行前的位置。

2.切点(Pointcut)
每个程序类都拥有多个连接点,如一个拥有两个方法的类,这两个方法都是连接点,即连接点是程序类中客观存在的事物,但在这些连接点中,如何定位到某个感兴趣的链接点上呢??AOP通过“切点”定位特定连接点。通过数据库查询的概念来理解切点和连接点的关系是:连接点相当于数据库中的记录,而切点相当于查询条件。
切点和连接点不是一对一关系,一个切点可以匹配多个连接点。
在Spring中,切点通过org.springframework.aop.pointcut接口进行描述,它使用类和方法作为连接点的查询条件,SpringAOP的规则解析引擎负责解析切点所设定的查询条件,找到对应的连接点。
3.增强:(Advice)
  增强就是植入到目标类连接点上的一段程序代码。在Spring中,增强除用于描述一段程序代码外,还拥有另一个和连接点相关的信息,这便是执行点的方位。结合执行点方位信息和切点信息,我们可以找到特定的连接点了。
  正因为增强包含了用于添加到目标连接点上的一段执行逻辑,又包含了拥有定位连接点的方位信息,所以Spring所提供的增强接口都是带方位名的:BeforeAdvice、AfterRetuningAdvice、ThrowAdvice、ArroundAdvice等。BeforeAdvice表示方法调用前的位置,而AfterRetuningAdvice表示访问返回后的位置。

  • a.ITarget
  • /**
     * @author 周宁
     * @Date 2019-07-22 16:31
     */
    public interface ITarget {
    
        void normal(String str);
    
        void exception(String str);
    }
  • b.TargetImpl
  • /**
     * @author 周宁
     * @Date 2019-07-22 16:32
     */
    public class TargetImpl implements ITarget {
        @Override
        public void normal(String hello) {
            System.out.println("normal invoke{" + hello + "}");
        }
    
        @Override
        public void exception(String hello) {
            System.out.println("exception invoke{" + hello + "}");
            throw new RuntimeException("throw ex");
        }
    }
  • c.BeforeAdvice
  • /**
     * @author 周宁
     * @Date 2019-07-22 16:34
     */
    public class MethodBeforeAdviceImpl implements MethodBeforeAdvice {
        @Override
        public void before(Method method, Object[] args, Object target) throws Throwable {
            System.out.println("before advice" + method.getName());
            if (null != args && args.length > 0) {
                for (int i = 0; i < args.length; i++) {
                    System.out.println("arguments" + (i + 1) + ":" + args[i]);
                }
            }
            System.out.println("target:" + target.toString());
        }
    }
  • d.AfterRetuningAdvice
  • /**
     * @author 周宁
     * @Date 2019-07-22 16:38
     */
    public class MethodAfterReturningImpl implements AfterReturningAdvice {
        @Override
        public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
            System.out.println("after advice" + method.getName());
            if (null != args && args.length > 0) {
                for (int i = 0; i < args.length; i++) {
                    System.out.println("arguments" + (i + 1) + ":" + args[i]);
                }
            }
            System.out.println("target:" + target.toString());
        }
    }
  • e.ThrowingAdvice
  • /**
     * @author 周宁
     * @Date 2019-07-22 16:39
     */
    public class ThrowAdviceImpl implements ThrowsAdvice  {
    
        public void afterThrowing(Method method, Object[] args, Object target, Exception ex) {
            System.out.println("after throwing" + method.getName());
            if (null != args && args.length > 0) {
                for (int i = 0; i < args.length; i++) {
                    System.out.println("arguments" + (i + 1) + ":" + args[i]);
                }
            }
            System.out.println("target:" + target.toString());
        }
    
    }
  • f.ArroundAdvice
  • /**
     * @author 周宁
     * @Date 2019-07-22 16:42
     */
    public class MethodInterceptorImpl implements MethodInterceptor {
    
        @Override
        public Object invoke(MethodInvocation invocation) throws Throwable {
            System.out.println("invoke start" + invocation.getMethod().getName());
            Object[] args = invocation.getArguments();
            if (null != args && args.length > 0) {
                for (int i = 0; i < args.length; i++) {
                    System.out.println("arguments" + (i + 1) + ":" + args[i]);
                }
            }
            Object proceed = invocation.proceed();
            System.out.println("invoke end");
            return proceed;
        }
    }
  • g.测试类
  • /**
     * @author 周宁
     * @Date 2019-07-22 16:45
     */
    public class Day12Test {
    
        @Test
        public void testBeforeAdvice(){
            TargetImpl target = new TargetImpl();
            ProxyFactory proxyFactory = new ProxyFactory();
            proxyFactory.setTarget(target);
            proxyFactory.addAdvice(new MethodBeforeAdviceImpl());
            ITarget proxy = (ITarget) proxyFactory.getProxy();
            proxy.normal("干");
        }
    
        @Test
        public void testReturnningAdvice(){
            TargetImpl target = new TargetImpl();
            ProxyFactory proxyFactory = new ProxyFactory();
            proxyFactory.setTarget(target);
            proxyFactory.addAdvice(new MethodAfterReturningImpl());
            ITarget proxy = (ITarget) proxyFactory.getProxy();
            proxy.normal("干");
        }
    
        @Test
        public void testThrowingAdvice(){
            TargetImpl target = new TargetImpl();
            ProxyFactory proxyFactory = new ProxyFactory();
            proxyFactory.setTarget(target);
            proxyFactory.addAdvice(new ThrowAdviceImpl());
            ITarget proxy = (ITarget) proxyFactory.getProxy();
            proxy.exception("干");
        }
    
        @Test
        public void testArroundAdvice(){
            TargetImpl target = new TargetImpl();
            ProxyFactory proxyFactory = new ProxyFactory();
            proxyFactory.setTarget(target);
            proxyFactory.addAdvice(new MethodInterceptorImpl());
            ITarget proxy = (ITarget) proxyFactory.getProxy();
            proxy.normal("干");
        }
    
        @Test
        public void testMultiAdvice(){
            TargetImpl target = new TargetImpl();
            ProxyFactory proxyFactory = new ProxyFactory();
            proxyFactory.setTarget(target);
            proxyFactory.addAdvice(new MethodBeforeAdviceImpl());
            proxyFactory.addAdvice(new MethodAfterReturningImpl());
            ITarget proxy = (ITarget) proxyFactory.getProxy();
            proxy.normal("干");
        }
    }
    
  •  

4.目标对象Target
  增强逻辑的植入目标类,如果没有AOP,目标业务类需要自己实现所有逻辑。
5.引介(Introduction)
  引介是一种特殊的增强,它为类添加一些属性和方法。这样即使一个业务类原本没有实现某个接口,通过AOP的引介功能,我们可以动态地位该业务类添加接口的实现逻辑,让业务类成为和这个接口的实现类。
6.织入(Weaving)
  织入是将增强添加对目标类具体链接点上的过程,AOP像一台织布机,将目标类、增强或者引介通过AOP这台织布机天衣无缝的编制在一起。
AOP的织入方式:
  1)编译期织入,这要求使用特殊的Java编译器
  2)类装载器织入,这要求使用特殊的类装载器
  3)动态代理织入,在运行期为目标类添加增强生成子类的方式。
7.代理(Proxy)
  一个类被AOP织入增强后,就产生一个结果类,它是融合了原类和增强逻辑的代理类。根据不同的代理方式,代理类既可以使和原类具有相同接口的类,也可能是员类的子类。
8.切面(Aspect)
  切面由切点和增强组成,它既包括横切逻辑的定义,也包括连接点的定义,Spring AOP就是负责实施切面的框架,它将切面所定义的横切逻辑织入到切面所指定的连接点中。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值