spring 中使用 aspectj

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

Extension methods

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);
  }
}

Pointcuts

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);

Advices

Allow a programmer to specify code to run at a join point matched by a pointcut.  The actions can be performed beforeafter, 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.    }

 

一篇总结 aop 的文章

 

转载于:https://my.oschina.net/lemos/blog/795535

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值