ASPECTJ
Aspectj 框架简介
All valid Java programs are also valid AspectJ programs, but AspectJ lets programmers define special constructs called aspects. Aspects can contain several entities unavailable to standard classes
Allow a programmer to add methods, fields, or interfaces to existing classes from within the aspect.
aspect VisitAspect {
void Point.acceptVisitor(Visitor v) {
v.visit(this);
}
}
Allow a programmer to specify join points (like method call, object instantiation, or variable access),All pointcuts are expressions (quantifications) that determine whether a given join point matches.
pointcut set() : execution(* set*(..) ) && this(Point);
Allow a programmer to specify code to run at a join point matched by a pointcut. The actions can be performed before, after, or around the specified join point.
after () : set() {
Display.update();
}
SPRING-ASPECTJ
spring2.0提供了Aspectj切点表达式的支持。
此外Aspectj的1.5版本新增了对注解开发的支持,允许直接在bean中定义切面。
一 搭建环境
使用Aspectj 需要导入Spring aop和aspectj相关jar包: aop规范 spring 对aop的实现 Aspectj 规范 spring 对Aspectj 的实现
二 切点表达式
1. execution:匹配方法的执行
2. within:匹配包或子类包中的方法
3. this:匹配实现接口的代理对象中的方法
4. target:匹配实现接口目标对象中的方法
5. args:匹配参数格式符合标准中的方法
6. bean:匹配指定bean对象中的方法
execution
作用:可以定义切入点方法的切入
语法:execution(<注解><访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
注意:返回值一般写* ,修饰符一般省略。方法,为方法的全限定名。
例如:
club.lemos.dao..*.*(..) 表示dao包下的任意子目录下的任意类下的使用任意参数列表的任意方法。
club.lemos.dao..UserDao+.*.(..) 表示dao包下的任意目录下的UserDao的实现类或者子类(UseDao+ 号的作用) 中的所有方法,参数列表任意。
within
作用:匹配指定包或子包中的方法
例子:
within(club.lemos.aop..*)
this
作用:匹配实现接口中的代理对象中的方法
例子:
this(club.lemos.aop.user.UserDao)
target
作用:匹配实现接口中的目标对象中的方法
例子:
target(club.lemos.aop.user.UserDao)
args
作用:匹配参数格式符合的方法
例子:
args(int,int)
bean(bean名称)
例如:bean("userDao") 此处写的内容,<bean id="userDao">
三 通知
AOP 的通知类型(一共六种,引介通知略)
before
after 方法结束后执行,无论是否抛出异常。
afterReturning 方法正常返回后执行,如果方法中抛出异常则无法执行。(针对方法有返回值)
afterThrowing
around 环绕通知
在spring.aop下的aspectj包下 分别有对应的实现类。
四 配置
基于xml的配置
切面类:
1. public class MyAspect {
2.
3. public void myBefore() {
4. System.out.println("之前执行!");
5. }
6. }
spring.xml配置文件
1. <?xml version="1.0" encoding="UTF-8"?>
2. <!-- 目标类-->
3. <bean id="customerDao" class="club.lemos.aspectjxml.CustomerDaoImpl"/>
4.
5. <!--切面类-->
6. <bean id="myAspect" class="club.lemos.aspectjxml.MyAspect"/>
7.
8. <!-- aop编程-->
9. <aop:config>
10. <!-- 配置切面-->
11. <aop:aspect ref="myAspect">
12. <!-- 配置切点,通知增强哪些方法-->
13. <aop:pointcut id="myPointCut" expression="execution(* club.lemos.aspectjxml..*.*(..))"/>
14. <!-- 确定通知类型-->
15. <aop:before method="myBefore" pointcut-ref="myPointCut"/>
16. </aop:aspect>
17. </aop:config>
18. </beans>
测试类:
1. /**
2. * 手动写工厂类和切面类
3. * Created by xfe1234 on 2016/11/27.
4. */
5. public class aspectjxml_test {
6. public static void main(String[] args) {
7.
8. String xmlPath= "club/lemos/aspectjxml/beans.xml";
9. ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
10. CustomerDao customerDao = (CustomerDao) applicationContext.getBean("customerDao");
11.
12. customerDao.delete();
13. customerDao.find();
14. customerDao.update();
15. customerDao.save();
16. }
17.
18. }
基于注解的配置
springmvc.xml 配置文件
1. <?xml version="1.0" encoding="UTF-8"?>
2.
3. <!-- 扫描包,使注解生效-->
4. <context:component-scan base-package="club.lemos.aspectjannotation"/>
5. <!--开启切面自动代理-->
6. <aop:aspectj-autoproxy/>
7.
8. </beans>
目标类
1. /**
2. * 目标类的实现
3. * Created by xfe1234 on 2016/11/27.
4. */
5. @Repository()
6. public class OrderDaoImpl implements OrderDao {
7. …
切面类
1. @Aspect
2. @Component
3. public class MyAspect {
4.
5. @Before("execution(* club.lemos.aspectjannotation..*.*(..))")
6. public void myBefore(JoinPoint joinPoint) {
7. System.out.println("前置通知,目标:");
8. System.out.println(joinPoint.getTarget()+",方法名称:");
9. System.out.println(joinPoint.getSignature().getName());
10. }
11.
12. @AfterReturning(value = "execution(* club.lemos.aspectjannotation..*.*(..))", returning = "returnVal")
13. public void myAfter(JoinPoint joinPoint, Object returnVal) {
14. System.out.println("后置通知,方法名称:" + joinPoint.getSignature().getName());
15. System.out.println("返回值:"+ returnVal);
16. }
17.
18. }
测试类
1. @RunWith(value = SpringJUnit4ClassRunner.class)
2. @ContextConfiguration("classpath:club/lemos/aspectjannotation/beans.xml")
3. public class aspectjannotation_test {
4.
5. @Autowired
6. private OrderDao orderDao;
7.
8. @Test
9. public void function1(){
10.
11. orderDao.delete();
12. System.out.println(orderDao.find());
13. orderDao.update();
14. orderDao.save();
15. }
16. }