前面记录了基于注解的aop 注解aop链接地址
基于xml配置的aop 配置aop链接地址
记录一下基于实现接口方式的aop
- 前置通知实现:MethodBeforeAdvice
- 后置通知实现:AfterReturningAdvice
- 异常通知实现:ThrowsAdvice
- 环绕通知实现:MethodInterceptor
前面三者都是来自org.springframework.aop.包下的
环绕通知不一样来自 org.aopalliance.intercept.包下本质就是用拦截器来实现 ,导包的时候注意不要导错
实现接口的方式实现aop步骤
- 导包 或者 maven 依赖
- 实现对应的通知类
- 将通知类和目标方法加入到ioc容器当中
- 通过配置将通知类和目标方法关联起来
项目架构
Operation 类 (业务类接口)
public interface Operation
{
// 加法
double add(double i, double j);
// 减法
double subtract(double i, double j);
// 乘法
double mul(double i, double j);
// 除法
double div(double i, double j);
}
OperationImpl 类 (业务实现类)
public class OperationImpl implements Operation
{
@Override
public double add(double i, double j)
{
return i+j;
}
@Override
public double subtract(double i, double j)
{
return i-j;
}
@Override
public double mul(double i, double j)
{
return i*j;
}
@Override
public double div(double i, double j)
{
return i/j;
}
}
LogBefore 类 (前置通知类)
/*
implements MethodBeforeAdvice 实现该类
重写 before 方法 实现前置通知
* */
public class LogBefore implements MethodBeforeAdvice
{
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable
{
System.out.println("我是前置通知,目标方法的方法名 "+ method.getName()+"\t目标对象" +o+"\t参数列表"+ Arrays.asList(objects));
}
}
LogAfterReturning 类 (后置通知类)
public class LogAfterReturning implements AfterReturningAdvice
{
@Override
public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable
{
System.out.println("我是后置通知,目标方法的方法名 "+ method.getName()+"\t目标对象" +o1+"\t参数列表"+ Arrays.asList(objects));
}
}
LogThrowing 类 (异常类)
public class LogThrowing implements ThrowsAdvice
{
// 异常类方法
public void afterThrowing(Method method, Object[] args, Object target, Throwable throwable){
System.out.println("我是异常通知,目标方法的方法名 "+ method.getName()+"\t目标对象" +target+"\t异常信息"+throwable);
}
}
LogAround 类(环绕通知类)
public class LogAround implements MethodInterceptor
{
@Override
public Object invoke(MethodInvocation invocation) throws Throwable
{
Object result = null;
try
{
System.out.println("我是 [环绕通知]的 前置通知");
result= invocation.proceed(); // 控制着目标方法是否执行
System.out.println("我是 [环绕通知]的 后置通知");
System.out.println("目标方法的返回值 "+result+"\t 目标对象 " +invocation.getThis()+"\t 调用方法的方法名" + invocation.getMethod().getName());
}
catch (Exception e)
{
System.out.println("我是 [环绕通知]的 异常通知");
}
finally
{
System.out.println("我是 [环绕通知]的 最终通知");
}
return result;
}
}
xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 将目标对象加载到ioc容器 -->
<bean id="operation" class="com.stone.aopdome.operation.impl.OperationImpl"></bean>
<!-- 将前置通知配置到ioc容器当中 -->
<bean id="before" class="com.stone.aopdome.proxy.LogBefore"></bean>
<!-- 将后置通知配置到ioc容器当中 -->
<bean id="after" class="com.stone.aopdome.proxy.LogAfterReturning"></bean>
<!-- 将异常通知配置到ioc容器当中 -->
<bean id="throwing" class="com.stone.aopdome.proxy.LogThrowing"></bean>
<!-- 将环绕通知配置到ioc容器当中 -->
<bean id="around" class="com.stone.aopdome.proxy.LogAround"></bean>
<!-- 将目标对象 和 通知 链接 起来 -->
<aop:config>
<!-- aop:pointcut全局的切面点表达式 -->
<aop:pointcut id="myPointcut" expression="execution(* com.stone.aopdome.operation.impl.OperationImpl.*(..))"/>
<!-- aop:advisor配置通知方法和切入点表达式进行关联 -->
<aop:advisor advice-ref="before" pointcut-ref="myPointcut"/>
<aop:advisor advice-ref="after" pointcut-ref="myPointcut"/>
<aop:advisor advice-ref="throwing" pointcut-ref="myPointcut"/>
<aop:advisor advice-ref="around" pointcut-ref="myPointcut"/>
</aop:config>
</beans>
测试类
public class SpringAopInterfaceTest
{
ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
@Test
public void testAopInterface1(){
Operation bean = ioc.getBean(Operation.class);
double add = bean.add(1, 3);
System.out.println(add);
}
}
执行结果