AspectJ 个基于 Java语言的 AOP 框架 。
基于XML配置开发的AspectJ
public class SomeServiceImpl implements ISomeService{
public void doFirst(){
System.out.println("执行dofirst");
}
public String doSecond(){
System.out.println("执行doSecond");
return "abcde";
}
@Override
public void doThird() {
//System.out.println("执行异常通知方法 "+ 3/0 );
System.out.println("执行doThird");
}
}
//切面
public class MyAspect {
public void before(JoinPoint jp) {
System.out.println("执行前置通知 jp="+jp);
//可以携带参数,切入点表达式,具体拿哪个表达式,匹配上的方法
}
public void before( ) {
System.out.println("执行前置通知");
}
public void afterReturning( ) {
System.out.println("执行后置通知");
}
public void afterReturning(Object result ) {
//后置通知可以获取目标方法的返回值
System.out.println("执行后置通知 result=" +result);
}
public Object around(ProceedingJoinPoint pip) throws Throwable {
//执行目标方法,需要有参数来调用目标方法
System.out.println("执行环绕通知方法,目标方法执行之前 " );
//执行目标方法,执行的结果需要带回去
Object result=pip.proceed();
System.out.println("执行环绕通知方法,目标方法执行之后 " );
//因为有返回值,故可以进行修改
if(result!=null) {
result =((String)result).toUpperCase();
}
return result;
}
void afterThrowding(Exception ex){
System.out.println("执行异常通知方法 ex=" +ex.getMessage());
}
void afterThrowding(){
System.out.println("执行异常通知方法 " );
}
void after(){
System.out.println("执行最终通知方法 " );
//无论有没有异常都会执行最终通知
}
}
xml
<!-- 注册切面 -->
<bean id="myAspect" class="com.spring.ascept02.MyAspect"></bean>
<!-- 注册目标对象 -->
<bean id="SomeService" class="com.spring.ascept02.SomeServiceImpl"></bean>
<!-- aop的配置 -->
<aop:config>
<aop:pointcut expression="execution(* *..ISomeService.doFirst(..))" id="dofirstpoint"/>
<aop:aspect ref="myAspect">
<aop:before method="before" pointcut-ref="dofirstpoint"/>
<aop:before method="before(org.aspectj.lang.JoinPoint)" pointcut-ref="dofirstpoint"/>
<aop:after-returning method="afterReturning" pointcut-ref="dofirstpoint"/>
<aop:after-returning method="afterReturning(java.lang.Object)" pointcut-ref="dofirstpoint" returning="result"/>
<aop:around method="around" pointcut-ref="dofirstpoint"/>
<aop:after-throwing method="afterThrowding(java.lang.Exception)" pointcut-ref="dofirstpoint" throwing="ex"/>
</aop:aspect>
</aop:config>
@Test
public void test01() {
ApplicationContext ctx=new ClassPathXmlApplicationContext("com/spring/ascept02/applicationContext.xml");
ISomeService hello =(ISomeService)ctx.getBean("SomeService");
hello.doFirst();
System.out.println("======================");
hello.doSecond();
System.out.println("======================");
hello.doThird();
}}
>
基于注解的AspectJ
@Aspect//表示当前类为切面
public class MyAspect {
//定义了一个切入点,叫doThirdPoint()
@Pointcut("execution(* *..ISomeService.doThird(..))")
public void doThirdPoint() {
}
@Before("doThirdPoint() ")
public void before(JoinPoint jp) {
System.out.println("执行前置通知 jp="+jp);
//可以携带参数,切入点表达式,具体拿哪个表达式,匹配上的方法
}
@Before("doThirdPoint() ")
public void before( ) {
System.out.println("执行前置通知");
}
@AfterReturning("doThirdPoint() ")
public void afterReturning( ) {
System.out.println("执行后置通知");
}
@AfterReturning(value="doThirdPoint() " , returning="result")
public void afterReturning(Object result ) {
//后置通知可以获取目标方法的返回值
System.out.println("执行后置通知 result=" +result);
}
@Around("doThirdPoint() ")
public Object around(ProceedingJoinPoint pip) throws Throwable {
//执行目标方法,需要有参数来调用目标方法
System.out.println("执行环绕通知方法,目标方法执行之前 " );
//执行目标方法,执行的结果需要带回去
Object result=pip.proceed();
System.out.println("执行环绕通知方法,目标方法执行之后 " );
//因为有返回值,故可以进行修改
if(result!=null) {
result =((String)result).toUpperCase();
}
return result;
}
@AfterThrowing(value="doThirdPoint() ", throwing="ex")
void afterThrowding(Exception ex){
System.out.println("执行异常通知方法 ex=" +ex.getMessage());
}
@AfterThrowing("doThirdPoint() ")
void afterThrowding(){
System.out.println("执行异常通知方法 " );
}
@After("doThirdPoint()")
void after(){
System.out.println("执行最终通知方法 " );
//无论有没有异常都会执行最终通知
}
}
<!-- 注册切面 -->
<bean id="myAspect" class="com.spring.ascept01.MyAspect"></bean>
<!-- 注册目标对象 -->
<bean id="SomeService" class="com.spring.ascept01.SomeServiceImpl"></bean>
<!-- 注册AspectJ的自动代理 -->
<aop:aspectj-autoproxy/>