AOP的注解就是把原本AOP里.xml配置文件里的配置以注释的方式表现出来,实际的作用是相同的,是简化代码工作量的一种方式,但是使用注解的方式不如使用.xml文件简单易懂,容易使他人看不懂你所书写的代码。
首先是在pom.xml中添加所需依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
然后在.xml文件中引入aop命名空间
<bean……
xmlns:aop="http://www.springframework.org/schema/aop"
……
……
xsi:schemaLocation="
……
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="此处为所要扫描的组件"></context:component-scan>
//开启组建扫描
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
//自动为Spring容器中那些匹配了@Aspectj切面的Bean创建代理,完成织面切入
接下来需要定义切面类:
使用@Aspect来标注这个类,表名此类为切面类
@Aspect
public class TimeAspect {
……
}
然后定义切点@Pointcut(此处为要织入的路径,即Aspectj表达式)标注在一个方法上
@Pointcut( "execution(* cn.itlaobing.dao.*.*(..))" )//此处表达式意为将切点织入dao包中的所有类的所有方法中
private void myPointcut(){
}
接下来使用以下注解来标注在所需插入的方法上表名所需插入的方法在何处执行:
@before 用于标注Before Advice定义所在的方法
@afterreturning 用于标注After Returning Advice定义所在的方法
@afterthrowing 用于标注After Throwing Advice定义所在的方法
@after 用于标注 After(Finally) Advice定义所在的方法
@around 用于标注Around Advice定义所在的方法
例如:@Before( "myPointcut()" )
public void before( JoinPoint joinPoint ){
// 将 日历对象 所表示的时间 设置为当前时间 ( 通过更改其内部的毫秒值 来实现 )
calendar.setTimeInMillis( System.currentTimeMillis() );
Date now = calendar.getTime();
String s = formater.format( now );
// 从 连接点 中获得 被执行的方法的 签名
Signature signature = joinPoint.getSignature();
// 从 方法签名 中获取方法名称
String name = signature.getName() ;
System.out.println( s + " 方法[ " + name + " ]准备执行" );
}
//此方法将会在dao包中的某个类的某个方法执行之前执行。
使用了 注解 的方式代替了配置文件,即以配置文件中的以下内容(举个栗子):
<bean id="advice" class="vip.ycpower.aop.Advice" />
<!-- 添加 AOP 配置 -->
<aop:config>
<!-- 全局切点 -->
<!-- id 用于指定切点名称 ( 将来可以通过切点名称来引用这个切点 )-->
<!-- expression 用于指定切点表达式 ( 使用特定的切点函数来筛选 连接点 )-->
<aop:pointcut id="myPointcut" expression="execution(* vip.ycpower.aop.Tiger.*(..))" />
<aop:aspect ref="advice" order="-250">
<aop:before pointcut-ref="myPointcut" method="before" />
<!--
<aop:around pointcut-ref="myPointcut" method="around" />
<aop:after-returning pointcut-ref="myPointcut" method="afterReturn" returning="returnValue" />
<aop:after-throwing pointcut-ref="myPointcut" method="afterThrow" throwing="ex" />
-->
<aop:after pointcut-ref="myPointcut" method="after" />
</aop:aspect>
<aop:aspect ref="timeAdvice" order="251">
<aop:before pointcut-ref="myPointcut" method="before" />
<aop:after pointcut-ref="myPointcut" method="after" />
</aop:aspect>
</aop:config>
其中order属性是在配置中书写了多个切面时,当执行同一个切入点时,不同切面的执行先后顺序是由“每个切面的order属性”而定的,order越小,则该该切面中的通知越先被执行。