AspectJ框架

AOP

1、动态代理
	实现方式:JDK动态代理,使用jdk中的Proxy,Method,InvocationHandler创建代理
		     JDK动态代理要求目标类必须实现接口
    cglib动态代理:是第三方的工具库,创建代理对象,原理是继承,通过继承目标类,创建子类
		          子类就是代理对象,要求目标类不能是final,方法也不能是final
2、动态代理的作用:
	1)在目标类源代码不改变的情况下,增加功能
	2)减少代码的重复
	3)专注业务逻辑代码
	4)解耦合,让你的业务功能和日志,事务非业务功能分离
3、AOP(Aspect Orient Programming)面向切面编程
	Aspect:   切面,给你的目标类增加的功能,就是切面,像上面的日志、事务都是切面	
		       切面的特点:一般都是非业务方法,独立使用的
	Orient:       面向,对着
	Programming: 编程
	OOP:         面向对象编程
4、怎样理解面向切面编程?
	1)需要在分析项目功能时,找出切面;
	2)合理的安排切面的执行时间(在目标方法前,还是在目标方法后)
	3)合理的安全切面执行的位置,在哪个类?哪个方法?增强功能

术语:

*Aspect:切面,表示增强的功能,就是一堆代码,完成某个功能。非业务功能,常见的切面功能
				有日志,事务,统计信息,参数检查,权限验证。
JoinPoint:连接点,连接业务方法和切面的位置,就某类中的一个业务方法
*Pointcut:切入点,指多个连接点方法的集合,多个方法
目标对象,给哪个类的方法增加功能,这个类就是目标对象
*  Advice:通知,通知表示切面功能执行的时间

切面三个关键要素

切面的功能代码====切面能干什么
切面的执行位置====使用Pointcut表示切面执行的位置
切面的执行时间====使用Advice表示时间,在目标方法之前,还是目标方法之后

aop的实现

aop是一个规范,是动态的一个规范化,一个标准
aop的技术实现框架:
1、spring:spring在内部实现了aop规范,能做aop的工作
spring主要在事务处理时使用aop,
我们项目开发中很少使用spring的aop实现,因为spring的aop比较笨重
2、aspectJ:一个开源的,专门做aop的框架,spring框架中集成了aspectJ框架,可以通过spring使用其功能
aspectJ框架实现aop有两种方式:
		1、使用xml的配置文件
		2、使用注解,我们在项目中做aop功能,一般都使用注解,aspectJ有5个注解。

学习aspectJ框架的使用

1、切面的执行时间,执行时间在规范中叫做Advice(通知、增强),
在aspectJ框架中使用注解表示,也可以使用xml配置文件中的标签
		1)@Before
		2)@AfterReturning
		3)@Around
		4)@AfterThrowing
		5)@After
2、切面执行的位置,使用的是切入点表达式。
		execution(访问权限 方法返回值 方法声明(参数) 异常类型)
		每个部分用空格分开,访问权限和异常类型可以省略
		*	表示多个字符 
		..	用在参数时表示多个参数,用在包名时表示当前包及其子包路径	
		+	用在类名后,表示当前类及子类,用在接口后,表示当前接口及实现类

举例:

//指定切入点为:任意公共方法:
	execution(public * *(..))
//任何一个以set开始的方法
	execution(* set*(..))
//定义在service包里的任意类的任意方法
	execution(* service.*.*(..))
//定义在service包或子包里的任意类的任意方法
	execution(* service..*.*(..))
//指定所有包下的service子包下所有类所有方法
	execution(* *..service.*.*(..))

前置通知

//@Aspect作用:表示当前类是切面类
//切面类:是用来给业务方法增加功能的类,这个类中有切面的功能代码
//位置:在类定义的上面
@Aspect
public class MyAspectJ{
	/*定义方法:方法是实现切面功能的。
		方法的定义要求:
		1.公共方法public
		2.方法返回void
		3.方法名称自定义
		4.方法可以有参数,也可以没有参数。
			如果有参数,参数不是自定义的,有几个参数类型可以使用
-----------------------------------------------------------------------------------------
	@Before:前置通知注解
	属性:value,是切入点表达式 ,表示切面的功能执行的位置。
	位道:在方法的上面
	特点:
	1.在目标方法之前先执行的
	2.不会改变目标方法的执行结果
	3.不会影响目标方法的执行。*/
    @Before(value="execution(* *..SomeServiceImpl.*(..))")
    public void isBefore(JoinPoint jp){	
------------------------------------------------------------------------------------
    	/*
    	指定通知方法中的参数: JoinPoint
		JoinPoint:业务方法,要加入切面功能的业务方法
		作用:可以在通知方法中获取方法执行时的信息,例如方法名称, 方法的参数列表。
		如果你的切面功能中需要用到方法的信息,就加入JoinPoint
		这个Joinpoint参数的值是由框架赋予,必须是 第一个位置的参数		*/
        jp.getSignature();//方法的全限定名称
        jp.getSignature().getName();//方法名
        Object args[] = jp.getArgs();//方法的参数列表
    }
}

后置通知

后置通知定义方法,方法是实现切面功能的。
方法的定义要求:
1.公共方法public
2.方法没有返回值
3.方法名称自定义
4.方法有参数的,推荐是object, 参数名自定义
/*
@AfterReturning
	属性::	1.value切入点表达式
			2. returning自定义的变量,表示目标方法的返回值的。
				自定义变量名必须和通知方法的形参名一样。
	位置:在方法定义的上面
	特点:	1.在目标方法之后执行的。
			2.能够获取到目标方法的返回值,可以根据这个返回值做不同的处理功能
			3.可以修改这个返回值
*/
@AfterReturning(value = "execution(* *..SomeServiceImpl.*(..))",
				returning = "res")
public void myAfterReturning(Object res){
	Student stu = (Student)res;
	stu.setName("李四");//如果返回值是一个引用类型,可以通过后置方法来修改返回值
}

环绕通知

环绕通知方法的定义格式
1.方法是公共的,public
2.必须有一个返回值,推荐使用object
3.方法名称自定义
4.方法有参效,固定的参数ProceedingJoinpoint
@Around:环绕通知
属性:value切入点表达式
位置:在方法的定义什么
特点:
1.它是功能最强的通知
2.在目标方法的前和后都能增强功能。
3.控制目标方法是否被调用执行
4.修改原来的目标方法的执行结果。 影响最后的调用结果
环绕通知,等同于jdk动态代理的,InvocationHandler接口
参数: ProceedingJoinPoint 就等同于Method
作用:执行目标方法的
返回值:就是目标方法的执行结果 ,可以被修改
    @Around(value = "execution(* *..SomeServiceImpl.doFirst(..))")
    public Object myAround(ProceedingJoinPoint pjp) throws Throwable {
        //实现环绕通知
       //方法之前执行,开始事务
        Object args[] =  pjp.getArgs();
        for (Object arg: args){
            if("zhangsan".equals(arg)){//控制业务方法的执行
                pjp.proceed();//执行方法
            }
        }
         //方法之前执行,提交事务
        return "abc";//改变方法的返回值
    }

异常通知

异常通知方法的定义格式
1.public
2.没有返回值
3.方法名称自定义
4.方法有个一个Exception,如果还有是JoinPoint,
/*
@AfterThrowing:异常通知
属性: 
 	 1.value 切入点表达式
	 2.throwinng 自定义的变量,表示目标方法抛出的异常对象。
 	 3.变量名必须和方法的参数名一样
特点:
	1.在目标方法抛出异常时执行的
	2.可以做异常的监控程序,监控目标方法执行时是不是有异常。
	3.如果有异常,可以发送邮件,短信进行通知
-------------------------------------------------------------------------*/
@AfterThrowing(value =execution(* *. . SomeServiceImpl . doSecond(..))",
throwing = "ex" )
public void myAfterThrowing(Exception ex) {
System.out .println("异常通知:方法发生异常时,执行: "+ex. getMessage());
//发送邮件,短信, 通知开发人员

最终通知

最终通知方法的定义格式
1.public
2.没有返回值
3.方法名称自定义
4.方法没有参数,如果有就是JoinPoint,
@After :最终通知
属性: value切入点表达式
位置:在方法的上面
特点:
	1.总是会执行
	2.在目标方法之后执行的
	3.一般用来做资源清除工作

PointCut

用途:定义和管理切入点, 如果项目中有多个重复的切入点表达式,可以使用PointCut进行代码复用。
属性:value切入点表达式
位置:在自定义的方法上面
特点:
当使用@Pointcut定义在一个方法的上面, 此时这个方法的名称就是切入点表达式的别名。
其它的通知中, value属性就可以使用这个方法名称,代替切入点表达式
@Around(value = "mypt())")
@Pointcut(value =execution(* * .. SomeserviceImpl. doThird(..))" )
public void mypt(){
	//无需代码
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值