一、AspectJ框架它定义的通知类型有6种
1.前置通知Before 相当于BeforeAdvice
2.后置通知AfterReturning 相当于AfterReturningAdvice
3.环绕通知 Around 相当于MethodInterceptor
4.抛出通知AfterThrowing 相当于ThrowAdvice
5.引介通知DeclareParents 相当于IntroductionInterceptor
6.最终通知After 不管是否异常,该通知都会执行
相比spring 的传统AOP Advice多了一个最终通知
二、关于代理方式选择
在spring的aop开发中,它使用的是代理方案,代理实现有两种:
1.jdk的proxy
2.cglib
spring框架默认情况下,会对有接口的类使用proxy代理。没有接口的类使用cglib代理
Proxy-target-class的值默认是false,它代表有接口使用proxy代理
问题:如果现在对目标要使用cglib代理(不考虑是否有接口)?
只需要将proxy-target-class设置为true.
applicationContext.xml
<!-- 目标 -->
<bean id="userService" class="brooker.aspect.UserServiceImpl" ></bean>
<!-- 通知 -->
<bean id="userServiceAdvice" class="brooker.aspect.UserServiceHelper"></bean>
<!-- 切面 -->
<aop:config>
<!-- 引用通知类 -->
<aop:aspect ref="userServiceAdvice">
<!-- 可以将切点pointCut抽取出来,后面直接引用即可 -->
<aop:pointcut expression="execution(* *.add(..))" id="pointCut"/>
<!-- 对切点(add方法)用Helper类中的before方法进行增强 -->
<aop:before method="before" pointcut-ref="pointCut"/>
<aop:around method="around" pointcut-ref="pointCut"/>
<aop:after-returning method="afterReturn" pointcut-ref="pointCut"/>
<aop:after-throwing method="afterThrow" pointcut-ref="pointCut"/>
<aop:after method="after" pointcut-ref="pointCut"/>
</aop:aspect>
</aop:config>
UserServiceHelper增强类
public class UserServiceHelper {
public void before() {
System.out.println("前置通知");
}
public void afterReturn() {
System.out.println("后置通知");
}
public Object around(ProceedingJoinPoint proceed) throws Throwable {
System.out.println("环绕前...");
Object value = proceed.proceed();
System.out.println("环绕后...");
return value;
}
public void afterThrow() {
System.out.println("发现了异常...");
}
public void after() {
System.out.println("最终通知...");
}
}
Test
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext.xml")
public class UserTest {
@Autowired
private UserService userService;
@Test
public void test1() {
userService.add();
}
}
结果:
前置通知
环绕前...
add...
环绕后...
后置通知
最终通知...