AOP之AspectJ的方式

原创
2016/03/31 16:56
阅读数 9

前面写了下spring的proxyFactoryBean,可以看出动态bean的局限很大,每个被代理的类都得在xml里配置,很繁琐,这里说下AspectJ的写法.


maven依赖

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.8</version>
</dependency>


spring-test.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: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/aop http://www.springframework.org/schema/aop/spring-aop.xsd">


    <aop:aspectj-autoproxy/>

    <bean id="student" class="Student"/>
    <!--<bean id="interceptor" class="ProxyStudent"/>-->
    <bean id="aspectJStudent" class="AspectJStudent"/>

    <!--<bean id="myPointcut" class="org.springframework.aop.support.NameMatchMethodPointcut">-->
        <!--&lt;!&ndash; 只对say方法拦截 &ndash;&gt;-->
        <!--<property name="mappedName" value="say"/>-->
    <!--</bean>-->

    <!--<bean id="myAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">-->
        <!--<property name="advice" ref="interceptor"/>-->
        <!--<property name="pointcut" ref="myPointcut"/>-->
    <!--</bean>-->

    <!--<bean id="proxyStudent" class="org.springframework.aop.framework.ProxyFactoryBean">-->
        <!--<property name="interfaces">-->
            <!--<list>-->
                <!--<value>Person</value>-->
            <!--</list>-->
        <!--</property>-->
        <!--<property name="interceptorNames">-->
            <!--<list>-->
                <!--&lt;!&ndash;<value>interceptor</value>&ndash;&gt;-->
                <!--<value>myAdvisor</value>-->
            <!--</list>-->
        <!--</property>-->
        <!--<property name="target" ref="student"/>-->
    <!--</bean>-->
</beans>


AspectJStudent.java

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

/**
 * Created by wangrui04 on 2016/3/31.
 */
@Aspect
public class AspectJStudent {

    @Pointcut("execution (* Student.say(..))")
    public void pointcut(){}

    @Around("pointcut()")
    public void around (ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("AspectJ around before");
        joinPoint.proceed();
        System.out.println("AspectJ around after");
    }

    @Before("pointcut()")
    public void before(JoinPoint joinPoint){
        System.out.println("AspectJ before");
    }

    @After("pointcut()")
    public void after(JoinPoint joinPoint){
        System.out.println("AspectJ after");
    }

    @AfterReturning("pointcut()")
    public void afterReturning(JoinPoint joinPoint){
        System.out.println("AspectJ after returning");
    }


}


BootMain.java

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;

/**
 * Created by wangrui04 on 2016/3/31.
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring-test.xml"})
public class BootMain {

//    @Resource(name = "proxyStudent")
    @Resource
    @Qualifier("student")
    private Person student;

    @Test
    public void testMain(){
        student.say();
        student.run();
    }

}


output

AspectJ around before
AspectJ before
hello world!
AspectJ around after
AspectJ after
AspectJ after returning
run fast!

  • 对比二种方式可以看出AspectJ的方式更加灵活,配置文件更少,更加强大.

  • 配置文件里启用<aspectj-autoproxy/>

  • 注意调用的顺序

  • pointcut的写法还支持很多,比如支持注解,这样就实现了只要被xx注解了,这个方法就会被拦截到,通常做日志拦截.

展开阅读全文
打赏
1
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
1
分享
返回顶部
顶部