我们知道,使用面向对象编程(OOP)有一些弊端,当需要为多个不具有继承关系的对象引入同一个公共行为时,例如日志、安全监测、权限管理等,只有在每个对象里引用公共的行为,这样程序中就产生了大量的重复代码,即不美观也不利于维护,所以就有了一个对面向对象编程的补充,即面向方面编程(AOP)。AOP所关注的方向是横向的,不同于OOP的纵向。
在Sping中,你可以使用@Aspect
注解非常容易地定义一个切面。Spring采用@Aspect
注解对POJO进行标注,从而定义一个包含切点信息和增强横切逻辑的切面,可以将这个切面植入到匹配的目标Bean中。下面我们来看下如何完成AOP的配置和实现。
开始配置AOP
首先我们先创建一个用于拦截的Bean。
假设这个类在我们实际应用中会有核心的业务,并且需要在这个类前后加入日志来跟踪调试。
1 | //执行项目业务逻辑的类 |
接着我们开始创建AOP类。
这个类是负责监听所有类的test方法在执行前和执行后的时候,打印相应的日志,并且还能控制这些方法在执行前和执行后之间的一些处理(即环绕方法)。
1 |
|
然后我们再创建一个spring-aop.xml配置文件。
1 |
|
至此,我们已经初步完成了AOP的配置。现在开始来测试看看效果。
开始测试。
1 | public static void main(String[] args) { |
如果不出意外,那么会打印结果:
1 | aroundTest1 |
Spring实现了对所有类的test方法进行扫描,我们可以很方便地在这些方法执行前后做一些日志的记录,这样就能与业务代码解耦。那么Spring究竟是如何实现AOP的?
我们看下spring-aop.xml这个配置文件,其中<aop:aspectj-autoproxy />
的配置会让Spring支持带有@Aspect
注解的AOP类。
然后再看下@Pointcut(value = "execution(* com.learn.aop.test*(..))")
,@Pointcut
是指哪些方法需要被执行”AOP”,里面的值是一个表达式(关于这个表达式的写法,大家可以问下度娘)。在注解下方定义一个test()
方法,注意这个方法必须要定义(方法名可以随意取一个),之后定义的执行前after
、执行后before
以及环绕方法around
都是需要依赖它的,它就相当于一个“扫描器”。接着我们就可以定义@After
、@Before
以及@Around
方法了。只需要在你定义的方法上加上这三种注解,对应的value
值是“扫描器”的方法。
这样,一个简单的AOP实现就完成了。