SpringAop使用-创新互联
文章目录
逻辑运算符不同的增强类型
引介方法例子
文章名称:SpringAop使用-创新互联
URL标题:http://cdiso.cn/article/dheoje.html
- Spring Aop
- 基本概念
- 简单使用
- AspectJ基本语法
- 切点表达式
- 在函数中使用通配符
- 逻辑运算符
- 不同的增强类型
- 引介方法例子
- 切点函数详解
- @annotation
- execution
- 通过方法签名定义
- 通过类来定义
- 通过类包来定义
基于AspectJ和基于schema的Aop命名的使用
在main方法中写上 System.getProperties().put(“sun.misc.ProxyGenerator.saveGeneratedFiles”, “true”);可以在com.sun.proxy路径下看到生成的代理类class
基本概念- 连接点(Joinpoint) 所有可以执行额外代码的地方,比如方法前,方法后的时候
- 切入点(Pointcut): 从众多的连接点根据条件找到实际执行代码的地方的点
- 增强(Advice): 实际执行额外逻辑的代码
- 目标对象(targer) :被增强目标类
- 引介(Introduction):可以让目标类实现额外得方法,类似动态继承接口
- 织入(weaving):将增强加入到切点得这个过程。有编译器织入(AspectJ原生),装载器织入(AspectJ原生),动态代理织入(spring原生aop,spring后面融入AspectJ,但是底层还是动态代理)
- 代理(proxy):最后实际运行的类,功能和目标方法一样,只是加入了增强
- 切面(Aspect):切入点+增强
目标对象的接口以及实现
public interface Hello {void say();
String tell(String mes);
}
public class HelloImpl implements Hello {@Override
public void say() {System.out.println("hi");
}
@Override
public String tell(String mes) {System.out.println(mes);
return mes;
}
}
实现一个切面
@Aspect
public class BeformAspect {@Before("execution(* say(..))")
public void print()
{System.out.println("before");
}
}
- @Aspect表示定位为一个切面
基于schema配置xml
使用
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
Hello hello = (Hello)applicationContext.getBean("hello");
hello.say();
AspectJ基本语法
切点表达式在函数中使用通配符符号 | 作用 |
---|---|
* | 匹配任意字符,但只能匹配上下文种的一个 |
…(两个点) | 匹配任意字符可以匹配上下文多个,但在表示类的时候,必须和*联合使用,表示入参单独使用 |
+ | 必须跟在类名后,代表类的子类,包括自己 |
注解 | 参数 | 作用 |
---|---|---|
@Before (前置) | value | 定义切点 |
argNames | 可以获得目标对象的参数,参数名要和目标的参数名一致,多个已逗号隔开 | |
@AfterReturning (后置) | value | 定义切点 |
pointcut | 显示定义将覆盖value,和value同义 | |
returning | 将目标的返回值绑定给增强方法 | |
argNames | 同前面一样 | |
@Around (环绕) | value | 定义切点 |
argNames | 同前面一样 | |
@AfterThrowing (异常) | value | 定义切点 |
pointcut | 同前面一样 | |
throwing | 将抛出的异常绑定到方法中 | |
argNames | 同前面一样 | |
@After (不管异常还是正常退出都会执行) | value | 定义切点 |
argNames | 同前面一样 | |
@DeclareParents (引介增强) | value | 定义切点 |
defaultImpl | 默认的接口实现类 |
比较特殊不同于其他增强类型的使用,
将HelloImpl融入SellerImpl类
public interface Hello {void say();
String tell(String mes);
}
public class HelloImpl implements Hello {@Override
public void say() {System.out.println("hi");
}
@Override
public String tell(String mes) {System.out.println(mes);
return mes;
}
}
public interface Seller {String sell(String goods);
}
public class SellerImpl implements Seller{@Override
public String sell(String goods) {System.out.println(goods);
return null;
}
}
介引切面
@Aspect
public class BeformAspect {@DeclareParents(value = "AspectJ.HelloImpl",defaultImpl = SellerImpl.class)
public Seller seller;
}
- value 切点,找到需要介引的目标
- defaultImpl 找到需要增强的具体实现类
- 下面的变量为defaultImpl的接口
配置文件
使用
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
//可以将HelloImpl强转为Seller
Seller hello = (Seller)applicationContext.getBean("hello");
System.out.println(hello);
切点函数详解
@annotation@Before("@annotation(AspectJ.Mytest)")
被注解标记的方法会执行切面注入
execution 通过方法签名定义匹配 所有public的方法(其他修饰符不行),第一个*代表返回值 第二个代表方法名,(…)表示任意入参
@Before("execution(public * *(..))")
任意返回值,任意参数,方法名字以ll结尾的方法
@Before("execution(* *ll(..))")
通过类来定义匹配Hello接口所有实现类,第一个*为返回值。(只包括接口定义的方法)
@Before("execution(* AspectJ.Hello.*(..))")
匹配Hello接口所有实现类,第一个*为返回值。(包括子类里不是接口的方法)
@Before("execution(* AspectJ.Hello+.*(..))")
通过类包来定义
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
文章名称:SpringAop使用-创新互联
URL标题:http://cdiso.cn/article/dheoje.html