Aspect Oriented Programming(AOP) 学习总结

 

AOP 概念

切面(Advisor):是AOP中的一个术语,表示从业务逻辑中分离出来的横切逻辑,比如性能监控,日志记录,权限控制等

 

增强: 增强代码的功能的类,横切到代码中。

目标:目标方法(JDK代理)或目标类(CGLIB代理)

代理:JDK代理,CGLIB代理。或是通过 ProxyFactory 类生产。

切点:通过一个条件来匹配要拦截的类,这个条件称为切点。如拦截所有带 Controller 注解的类。增强的条件。

连接点:作为增强方法的入参,可以获取到目标方法的信息。

 

演示:

     引入 jar 包

     引入 Spring 配置文件  :有两处的aop内容

     注入Mybefore 和 MyImpl

	<bean id="mybefore" class="com.kgc.aop.demo.Mybefore"></bean>
	<bean id="myImpl" class="com.kgc.aop.demo.MyImpl"></bean>

注: MyImpl 位 具体实现类 , Mybefore 是实现这个实现类时 插入 的一些 跟具体实现类无任何关系的操作

下面是 AOP 的XML配置具体操作

	<!-- 代理已经配置好了  -->
	<!-- 标签内不是aop的配置  -->
	<aop:config>
		<!-- 切入点 -->
		<aop:pointcut id="myPointCut" expression="execution(* com.kgc.aop.demo.MyImpl.test01(..))" />
		<!-- 切面 -->
		<aop:aspect ref="mybefore">
		 	<!-- 通知  -->
			<aop:before method="before" pointcut-ref="myPointCut" />
			<aop:after method="after" pointcut-ref="myPointCut" />
			<aop:after-returning method="returning" pointcut-ref="myPointCut" />
			<aop:after-throwing method="throwing" pointcut-ref="myPointCut" />
			 
			<aop:around method="around" pointcut-ref="myPointCut" />   
		</aop:aspect>
	</aop:config>

 

AOP的通知标签 : Weaving(织入):对方法进行增强

        before                 在某连接点之前执行的通知

        after-throwing     在方法抛出异常退出时执行的通知

        after-returning    在某连接点正常完成之后通知(如果抛出异常就不执行到)

        after                   在某连接点退出时执行的通知(一定会执行)

        around               包围一个连接点的通知

 

切入点:  作用: 匹配连接点

增强: 增强代码的功能的类,横切到代码中。

切入点表达式语法

     execution(

         Modifiers-pattern?                                      --方法操作权限【可选】

         Ret-type-pattern                                         --返回值    【必选】

         declaring-type-pattern?                              --方法所在包 【可选】

         name-pattern (param-pattern)                    --方法名(参数) 【必选】

         throws-pattern?                                           --异常   【可选】

     )

               //  表示com.kgc.aop.demo 包下任意类和任意方法

               execution(* com.kgc.aop.demo.MyImpl.test01(..))

                //  表示任意多个子包

                execution(* com..*.*(*))

        切入点表达式进一步剖析

                    *  :  1、表示任意类和包名

                              2、表示任意方法名

                              3、表示任意一个类型的参数

                    ..  :     1、在类型模式中,表示任意多个子包

                              2、对参数没有任何限制

                    + :   1、匹配指定类型的子类型(子类)

 

 

 

 

@AspectJ 支持

       1、    是注解形式的 AOP  方便使用 简化配置

       2、    AspectJ 是Spring AOP 的默认 实现工具

   注意  :  使用注解是为了简化配置(而不是减掉配置)

 

示例

    1、开启注解支持

	<!-- 开启AOP 的注解支持 -->
	<aop:aspectj-autoproxy />

    2、在AOP 代理源上加入 AOP支持      加上 @Aspect 标签

/*
		<aop:pointcut id="myPointCut" expression="execution(* com..*.*(com.kgc.aop.demo.Child+))" />
		<aop:aspect ref="mybefore">
			<aop:before method="before" pointcut-ref="myPointCut" />
		</aop:aspect>
	
 */

@Aspect
public class AnnoProxy {
      ...
}

    3、将AOP 代理和目标对象注入到Spring

	
	@Pointcut(value="execution(* com..*.*(int))")
	public void pointCut(){}
	
	@Pointcut(value="within(com.kgc.aop.annocation.TargetImpl)")
	public void pointCut2(){}
	
	@Before(value="pointCut2()")
	public void methodBefore(JoinPoint jp){
		System.out.println("这是方法开始之前!入参jp="+jp.getArgs()[0]);
		System.out.println("这是方法开始之前!签名="+jp.getSignature());
	}
	
	@After(value="pointCut2() && args(a) ")
	public void methodAfter(int a){
		System.out.println("这是方法执行之后,入参a="+a);
	}
	
	@AfterThrowing(value="pointCut2()",throwing="e")
	public void afterThrowing(Exception e){
		System.out.println("抛出异常啦,e="+e.getMessage());
	}
	
	@Around(value="pointCut2()")
	public void around(ProceedingJoinPoint pjp){
		System.out.println("around~!");
		try {
			Object result = pjp.proceed();
			
			System.out.println("result = "+result);
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("方法执行之后!");
		
	}

around 详解:

当执行around 是时候 是不跳入 我们的目标实现 方法的, 只会执行 before 操作,其他操作全部不执行,

不过我们可以 用 ProceedingJoinPoint 中的 .proceed() 方法,我养我们就可以跳入 执行了。

 

 传参

      1、使用joinPoint 传参   

           如上面的实例

      注:ProceedingJoinPoint 是 JoinPoint 的子类

      2、agrs

 

 

通知的执行顺序

      1、继承 Order

public class OrderProxy implements Ordered

     2、重写方法 ,  赋值权重

	@Override  //权重
	public int getOrder() {
		// TODO Auto-generated method stub
		return 20;
	}

 

 

AOP 设计实战  ( 老师的经验)

  •       AOP 尽量拦截方法,而不是字段
  •       AOP 的使用用遵循如下原则:

               大部分或全部模块都需要使用的通用功能

               预计未来功能扩展的可能性比较大的地方

  •       AOP 设计应遵循正交原则

               先进的后出 后进的先出

  •        尽量对粗粒度对象使用 AOP
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值