AOP详解(1)

什么是AOP:
        假设我们把业务类看成一段圆木,将业务方法看成截断圆木的最内层的年轮,对最内层代码的修饰是外面层层包裹的外部年轮,这就是是横切代码的由来。
        AOP希望将分散在各个业务逻辑代码中的相同代码通过横向切割的方式抽取到一个独立的模块中,还业务逻辑一个清新的世界。
        AOP术语:
                连接点:程序执行的某个特定的位置:类初始化前、类初始化后、类某个方法调用前、类某个方法调用后、方法抛出异常后。一个类或者一段程序>代码拥有一些具有边界性质的特定点就是连接点。
                切点:每个程序类中由许多连接点,AOP通过“切点”定位特定连接点。一个切点对应多个连接点。
                增强:增强是织入目标类连接点上的一段程序代码。
                目标对象:增强逻辑的织入目标类
                引介:引介是特殊的增强,用来为类添加一些属性和方法。
                织入:织入是将增强添加到目标类具体连接点上的过程。
                代理:一个类被AOP织入增强后,就产生一个结果类,它融入了原类和增强逻辑的代理类。
                切面:切面是由切点和增强(引介)组成,它既包括了横切逻辑的定义,也包含了连接点的定义,Spring AOP就是负责实施切面的框架,它将切面>定义的横切逻辑织入到切面指定的连接点中。

Spring AOP使用两种代理机制:一种是基于JDK的动态代理,另一种是基于CGLib的动态代理。之所以用两种代理机制是因为:很大程度上JDK本身只提供接口的代理,
而不支持类的代理。
        JDK动态代理:
                主要涉及java.lang.reflect包中的两个类:Proxy和InvocationHandler.其中InvocationHandler是一个接口,可以通过实现该接口定义横切逻辑,
并且通过反射机制调用目标类的代码,动态将横切逻辑和业务逻辑编织在一起。
        CGLib采用字节码技术,可以为一个类创建一个子类,并在子类中采用方法拦截技术拦截所有父类方法的调用,并顺势织入横切逻辑

创建增强类:
        Spring使用增强类定义横切逻辑,同时由于Spring只支持方法连接点,增强还包括了在方法的哪一点加入横切代码的方位信息,还包括部分连接点的信息。
        Spring支持五种增强接口:
                        前置增强
                        后置增强
                        环绕增强
                        异常抛出增强
                        引介增强
        这些增强接口都有一些方法,通过实现这些接口方法,在接口方法中定义横切逻辑就可以将他们织入到目标类方法的相应连接点位置。
        前置增强:
                保证使用礼貌用语的实例:
                package com.baobaotao.advice;
                public interface Waiter{
                        void greetTo(String name);
                        void serveTo(String name);
                }
                现在我们来看一个训练不足的服务生的服务情况:
                package com.baobaotao.advice;
                public class NaiveWaiter implements Waiter{
                        public void greerTo(String name){
                                System.out.println("greet to"+name+"..");
                        }
                        public void serveTo(String name){
                                System.out.println("serving"+name+"...");
                        }
                }
                构建增强:
                package com.baobaotao.advice;
                import java.lang.reflect.Method;
                import org.springframework.aop.MethodBeforeAdvice;
                public class GreetingBeforeAdvice implements MethodBeforeAdvice{
                        public void before(Method method,Object[] args,Object obj)throws Throwable{
                                String clilentName=(String)args[0];
                                System.out.println("How arg you! Mr."+clientName)+".");
                        }
                }
        注意:before(Method method,Object[] args,Object obj)throws Throwable中method 为目标类的方法,args是目标类方法的入参,而obj是目标类实例。>当该方法发生异常时,将阻止目标类方法的执行。
        具体实施:
                package com.baobaotao.advice;
                import org.springframework.aop.BeforeAdvice;
                import org.springframework.aop.framework.ProxyFactory;
                public class TestBeforeAdvice{
                        public static void main(String[] args){
                                Waiter target=new NaiveWaiter();
                                BeforeAdvice advice=new GreetingBeforeAdvice();
                                ProxyFactory pf=new ProxyFactory();
                                pf.setTarget(target);
                                pf.addAdvice(advice);

                                Waiter proxy=(Waiter)pf.getProxy();
                                proxy.greetTo("john");
                                proxy.serveTo("Tom");
                        }
                }

        ProxyFactory:
                ProxyFactory内部就是使用JDK或CGLib代理的技术,将增强应用到目标类中。我们可以通ProxyFactory的setInstance(Class[] interfaces)指定针
对接口进行代理,ProxyFactory就是使用JdkDynamicAopProxy;如果针对类的代理则使用Cglib2AopProxy。
        我们还可以使用Spring的配置以“很Spring方式”声明一个代理:
                <bean id="greetingAdvice" class="com.baobaotao.advice.GreetingBeforeAdvice"/>
                <bean id="target" class="com.baobaotao.advice.NaviWaiter"/>
                <bean id="waiter" class="org.springframework.aop.framework.PorxyFactoryBean" p:proxyInterfaces="com.baobaotao.advice.Waiter" p:interceptorNames="greetingAdvice" p:target-ref="target"/>

        后置增强:
                package com.baobaotao.advice;
                import java.lang.reflect.Method;
                import org.springframework.aop.AfterReturningAdvice;
                public class GreetingAfterAdvice implements AfterReturningAdvice{
                        public void afterReturning(Object returnObj,Method method,Object[] args,Object obj)throws Throwable{
                                System.out.println("Please enjoy youself!");
                        }
                }
        环绕增强:
                package com.baobatao.advice;
                import org.aopalliance.intercept.MethodInterceptor;
                import org.aopalliance.intercept.MethodInvocation;
                public class GreetingInterceptorimplements MethodInterceptor{
                        public Object invoke(MethodInvocation invokecation)throws Throwable{
                                Object[] args=invocation.getArguments();
                                String clientName=(String)args[0];
                                System.out.println("How are you! Mr."+clientName+".");
                                Object obj=invocation.proceed();
                                System.out.println("Please enjoy yourself!");
                                return obj;
                        }
                }



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring AOP(面向切面编程)是Spring框架中的一个模块,用于提供横切关注点(Cross-Cutting Concerns)的支持。横切关注点是与应用程序的核心业务逻辑无关的功能,例如日志记录、性能统计、事务管理等。 在Spring AOP中,通过定义切面(Aspect)来捕获横切关注点,并将其应用到目标对象的方法中。切面由切点(Pointcut)和通知(Advice)组成。切点定义了在何处应用通知,通知则定义了在切点处执行的操作。 Spring AOP支持以下几种类型的通知: 1. 前置通知(Before Advice):在目标方法执行之前执行的通知。 2. 后置通知(After Advice):在目标方法执行之后执行的通知,不管方法是否抛出异常。 3. 返回通知(After Returning Advice):在目标方法成功执行并返回结果后执行的通知。 4. 异常通知(After Throwing Advice):在目标方法抛出异常后执行的通知。 5. 环绕通知(Around Advice):围绕目标方法执行的通知,可以在方法调用前后执行自定义操作。 除了通知,Spring AOP还支持引入(Introduction)和切点表达式(Pointcut Expression)等功能。引入允许为目标对象添加新的接口和实现,而切点表达式则允许开发人员定义切点的匹配规则。 要在Spring应用程序中使用AOP,需要进行以下步骤: 1. 引入Spring AOP的依赖。 2. 配置AOP代理。 3. 定义切面和通知。 4. 配置切点和通知之间的关系。 总之,Spring AOP提供了一种便捷的方式来处理横切关注点,使得开发人员可以将关注点与核心业务逻辑分离,提高代码的可维护性和可重用性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值