在spring2.0以上版本中,可以使用基于AspectJ注解或者基于xml配置aop。

一、启用AspectJ注解

在spring中启用AspectJ注解支持,一共4步:

  1. 要在spring应用中使用AspectJ注解,必须在classpath下包含AspectJ类库:aopalliance.jar,aspectj.weaver.jar,spring-aspects.jar。
  2. 将aop scheam添加到<beans>根元素中。
  3. 要在spring ioc容器中启用AspectJ注解支持,只要在Bean配置文件中定义一个用的xml元素<aop:aspectj-autoproxy>。
  4. 当spring ioc容器侦测到bean配置文件中的<aop:aspectj-autoproxy>元素时,会自动为AspectJ切面配置的bean创建代理。

二、实现基本逻辑

这是要导入的包结构,推荐使用maven:

1

先实现基本逻辑,再考虑加入切面处理:

运行结果:

基本的运算实现了。

三、添加日志功能

一共4个步骤。

首先在程序逻辑中寻找横切关注点,因为日志是一个关联的功能相似的横切关注点,所以可以抽取出来做一个切面。

(1)先创建一个日志类

(2)如何把这个类设置为切面?

  1. 首先把这个类放进ioc容器之中(例如:使用注解形式加上一个@Component)。
  2. 然后把这个类声明为切面(加上@Aspect注解)。

变成了这样:

光是配置切面还是不够的。

(3)告诉这个日志方法在哪些类的哪些方法开始执行之前执行

加上注解@Before

声明该方法是一个前置通知:声明该方法在目标方法开始之前执行。

在什么目标方法开始之前执行。

变成了这样:

(4)配置xml文件

使切面中的注解起作用。

想要调用一个目标方法,当这个目标方法与@Before注解声明的方法相一致的时候,aop框架会自动为目标方法所在的类生成代理对象,在调用该目标方法之前把前置方法加进去。

运行结果:

发现日志功能已经成功添加进去了。

(5)加强

但是现在只有the method begins呀,我们的参数到哪里去了,可以加上参数吗?

当然可以,需要引入一个概念叫连接点.

before方法引入连接点:

输出结果:

1.joinpoint 连接点,我理解为代理运行的函数对象

  1. methodname 是方法名称。
  2. getSignature() 获取签名。
  3. getName() 获取方法名称。

joinPoint.getArgs()获得函数的参数,是一个Object对象,所以List的泛型输入也要是Object对象。

2.那么问题来了,这里有一个add一个sub操作,怎么只显示一条日志,不是一个函数对应一个日志吗?

那是因为:

@Before注解中只适配了@Before(“execution(public int aopimpl.calculator.add(int, int))”),add这个方法而已。

如果把add改成*,@Before注解就会自动适配calculator下的所有方法。

输出结果:

成功输出日志。

四、总结一下

1.加入jar包。

2.在配置文件中加入aop的命名空间(aop),如果导入注解类和bean还需要加入context和bean的命名空间。

3.使用基于注解的方式。

(1)在配置文件加入如下配置

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

(2)把横切关注点的代码抽象到切面的类中(写方法类

i.首先切面要放在ioc容器中,切面是ioc容器中的bean,即加入@Component注解。

ii.切面还需要加入@Aspect注解。

(3)在类中声明各种通知

i.声明一个方法。

ii.在方法加上通知注解。

一共5种:

  1. @Before:前置通知,在方法执行之前执行。
  2. @After:后置通知,在方法执行之后执行。
  3. @AfterRunning:返回通知,在方法返回结果之后执行。
  4. @AfterThrowing:异常通知,在方法抛出异常之后执行。
  5. @Around:环绕通知,围绕着方法执行。

iii.注意注解的时间点。

iiii.如果需要方法细节,可以在方法中声明一个类型为JointPoint的参数,然后就能访问链接细节,方法名称和参数值。

发表评论

电子邮件地址不会被公开。 必填项已用*标注