前面提到的方式二的配置内容如下:
<!-- 切面方法二 -->
<bean id="writeLog2" class="com.gary.aop.writeLog2"></bean>
<aop:config>
<aop:aspect ref="writeLog2">
<aop:pointcut expression="execution(* com.glodon.service.*.*(..))" id="ddd"/>
<aop:before method="before" pointcut-ref="ddd"/>
<aop:after method="after" pointcut-ref="ddd"/>
</aop:aspect>
</aop:config>
它有三块内容:
1.配置切面类的bean
2.配置切入点
3.绑定通知
这三块内容都可以通过注解搞定,新创建一个切面类:
@Aspect
@Component
public class writeLog3 {
@Before("execution(* com.glodon.service.*.*(..))")
public void before(){
System.out.println("--方法执行前执行--");
}
@After("execution(* com.glodon.service.*.*(..))")
public void after(){
System.out.println("----方法执行后执行----");
}
}
在spring配置文件中配置扫描此文件。
<!-- 切面方法三 注解-->
<context:component-scan base-package="com.gary.aop"></context:component-scan>
还需要添加一行配置:开启aop的注解扫描
<!-- 开启aop的注解扫描 -->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
测试,输出:
--方法执行前执行--
--func1--
----方法执行后执行----
--方法执行前执行--
--func2--
----方法执行后执行----
--方法执行前执行--
--func3--
----方法执行后执行----
Spring AOP相关注解及含义如下:
@Aspect:用于声明方面组件
@Before:用于声明前置通知
@AfterReturning:用于声明后置通知
@After:用于声明最终通知
@Around:用于声明环绕通知
@AfterThrowing:用于声明异常通知
再演示一个环绕通知:
@Around("execution(* com.glodon.service.*.*(..))")
public void around(ProceedingJoinPoint jp){
String className = jp.getTarget().getClass().getName();
String methodName = jp.getSignature().getName();
System.out.println(className+"的"+methodName+"方法--环绕前");
try {
jp.proceed();// 调用方法,不执行的话方法将不会被执行
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println(className+"的"+methodName+"方法--环绕后");
}
调用方法的地方屏蔽两个,方便查看效果
@RequestMapping("testAOP")
public String testAOP(){
//userService.func1();
//userService.func2();
userService.func3(3);
return "success";
}
运行输出:
com.glodon.service.UserService的func3方法--环绕前
--方法执行前执行--
--func3--
com.glodon.service.UserService的func3方法--环绕后
----方法执行后执行----
如果屏蔽jp.proceed(),业务方法将不会被执行:
// jp.proceed();
com.glodon.service.UserService的func3方法--环绕前
com.glodon.service.UserService的func3方法--环绕后
----方法执行后执行----