引入通知是一种特殊的通知类型。它通过为接口提供实现类,允许对象动态地实现接口,就像对象已经在运行时扩展了实现类一样。
引入通知可以使用两个实现类 MaxCalculator 和 MinCalculator, 让 PureCalculator动态地实现 IMaxCalculator 和 IMinCalculator 接口。 而这与从 MaxCalculator 和 MinCalculator中实现多继承的效果相同。但却不需要修改 PureCalculator的源代码。引入通知也必须在切面中声明,在切面中,通过为任意字段添加@DeclareParents 注解来引入声明。注解类型的 value 属性表示哪些类是当前引入通知的目标。value 属性值也可以是一个 AspectJ 类型的表达式,可以将一个接口引入到多个类中。defaultImpl 属性中指定这个接口使用的实现类。
示例
1. 添加模型接口和类
package xyz.huning.spring4.aop.calculator;
public interface ICalculator {
double add(double x,double y);
double sub(double x,double y);
double mul(double x,double y);
double div(double x,double y);
}
package xyz.huning.spring4.aop.calculator;
public interface IMaxCalculator {
double max(double x,double y);
}
package xyz.huning.spring4.aop.calculator;
public interface IMinCalculator {
double min(double x,double y);
}
package xyz.huning.spring4.aop.calculator;
import org.springframework.stereotype.Component;
@Component
public class PureCalculator implements ICalculator {
@Override
public double add(double x, double y) {
System.out.println("execute method add ...");
return x + y;
}
@Override
public double sub(double x, double y) {
System.out.println("execute method sub ...");
return x - y;
}
@Override
public double mul(double x, double y) {
System.out.println("execute method mul ...");
return x * y;
}
@Override
public double div(double x, double y) {
System.out.println("execute method div ...");
return x / y;
}
}
package xyz.huning.spring4.aop.calculator.aopimport.annotation;
import xyz.huning.spring4.aop.calculator.IMaxCalculator;
public class MaxCalculator implements IMaxCalculator {
@Override
public double max(double x, double y) {
System.out.println("execute max method ...");
return x > y ? x : y;
}
}
package xyz.huning.spring4.aop.calculator.aopimport.annotation;
import xyz.huning.spring4.aop.calculator.IMinCalculator;
public class MinCalculator implements IMinCalculator {
@Override
public double min(double x, double y) {
System.out.println("execute min method ...");
return x < y ? x : y;
}
}
package xyz.huning.spring4.aop.calculator.aopimport.annotation;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareParents;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import xyz.huning.spring4.aop.calculator.IMaxCalculator;
import xyz.huning.spring4.aop.calculator.IMinCalculator;
@Order(3)
@Aspect
@Component
public class CalculatorMaxMinAspect {
@DeclareParents(value="* *.PureCalculator",defaultImpl=MaxCalculator.class)
private IMaxCalculator maxCalculator;
@DeclareParents(value="* *.PureCalculator",defaultImpl=MinCalculator.class)
private IMinCalculator minCalculator;
}
2. 添加配置文件
<?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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!--自定义bean扫描范围--> <context:component-scan base-package="xyz.huning.spring4.aop.calculator"></context:component-scan> <!--使Aspectj注解启作用--> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
3. 添加测试类
package xyz.huning.spring4.aop.calculator.aopimport.annotation;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import xyz.huning.spring4.aop.calculator.IMaxCalculator;
import xyz.huning.spring4.aop.calculator.IMinCalculator;
public class Main {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("calculator-aop-annotation.xml");
IMaxCalculator maxCalculator = ctx.getBean("pureCalculator", IMaxCalculator.class);
maxCalculator.max(30, 40);
IMinCalculator minCalculator = ctx.getBean("pureCalculator", IMinCalculator.class);
minCalculator.min(30, 40);
((ClassPathXmlApplicationContext)ctx).close();
}
}
4. 执行结果