spring-aop-aspectj

🌳 spring-aspectj

🍁 spring-aspectj-简介

Spring 2.0之后,Spring AOP整合了AspectJ。我们可以用Aspect语法定义切面(Aspect),但是织入过程(Weaving)还是Spring AOP完成

🍂 spring-aspectj-API

TypePatternClassFilter - 采用aspectj表达式匹配类

AspectJExpressionPointCut - 采用aspectj表达式匹配方法

AspectJPointcutAdvisor - 采用aspectj的Advisor(可以理解为spring aop定义的切面)

ProxyFactoryBean - 手动织入

AspectJAwareAdvisorAutoProxyCreator - 自动织入

ProceedingJopintCut - 用在@Advice中

  • getTarget() - 获取target
  • getThis() - 获取proxy
  • getArgs() - 获取参数
  • proceed() - 执行方法

🌲 spring-aspectj -手动织入

1️⃣ 写Spring Aop的Advice​

@Component("catBefore")
public class CatBeforeAdvice implements MethodBeforeAdvice {

    // 前置通知
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("Before - cat准备捕鱼 !!!");
    }
}

2️⃣ 使用ProxyFactoryBean织入AspectJExpressionPointcut

 <!-- beforeAdvisor -->
<bean id="beforeAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
    <property name="pointcut">
        <bean class="org.springframework.aop.aspectj.AspectJExpressionPointcut">
            <property name="expression" value="execution(* com.yuki.aop..Cat.*(..))" />
        </bean>
    </property>
    <property name="advice" ref="catBefore" />
</bean>

<!-- aspectj-手动织入 -->
<bean name="cat" class="org.springframework.aop.framework.ProxyFactoryBean">
    <!-- 不使用cglib代理 -->
    <property name="proxyTargetClass" value="true" />
    <property name="optimize" value="true" />
    <!-- 代理 -->
    <property name="target" ref="catTarget" />
    <property name="proxyInterfaces" value="com.yuki.aop.CatFace" />
    <property name="interceptorNames" value="beforeAdvisor" />
</bean>

🍀 Spring-aspectj-自动织入-注解

用到的注解如下

@EnableAspectJAutoProxy - 开启注解支持

<aop:aspectj-autoproxy /> - 开启注解支持

@Pointcut - 定义切点

@Before@After@AfterThrowing@AfterReturning@Around - 定义切面

1️⃣ 开启注解支持

@EnableAspectJAutoProxy
@Configuration
@ComponentScan("com.yuki.aspect")
public class AspectConfig {
}

或者如下方式

<aop:aspectj-autoproxyproxy-target-class="true"/>

2️⃣ 使用@AspectJ注解写切面

@Aspect
@Component("catAspect")
public class CatAspect {

    // 定义切点
    @Pointcut("execution(* com.yuki.aspect..Cat.*(..))")
    public void catPoint() {}

    // Before Advice
    @Before("catPoint() && args(tool) && @annotation(anno)")
    public void beforeFish(String tool, CatAnno anno) {
        System.out.println("before  - Cat在准备装备!!! -- " + tool + "-----" + anno.values().toString());
    }

    // After throwing
    @AfterThrowing("catPoint()")
    public void afterThrow() {
        System.out.println("throwing - cat捕鱼失败 !!!");
    }

    // after return
    @AfterReturning("catPoint()")
    public void afterReturn() {
        System.out.println("return - Cat捕鱼成功 !!!");
    }

    // After
    @After("catPoint()")
    public void after() {
        System.out.println("after - Cat最后回到了家 !!!");
    }

    // Around
    @Around("catPoint()")
    public void around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("Around-------------");
        joinPoint.proceed();
        System.out.println("Around-------------");
    }
}

🍃Spring-aspectj-自动织入-xml方式

使用如下

<!-- aop -->
<aop:config>
    <!-- pointcut -->
    <aop:pointcut id="catPoint" expression="execution(* com.yuki.aspect..Cat.*(..))"/>
    <aop:pointcut id="catPointWithParam" expression="execution(* com.yuki.aspect..Cat.*(..)) &amp;&amp;  args(tool) &amp;&amp;  @annotation(anno)"/>
    <!-- aspect -->
    <aop:aspect id="catAspect" ref="catAspect">
        <!-- advice -->
        <aop:before method="beforeFish" pointcut-ref="catPointWithParam" />
        <aop:after method="after" pointcut-ref="catPoint" />
        <aop:after-returning method="afterReturn" pointcut-ref="catPoint" />
        <aop:after-throwing method="afterThrow" pointcut-ref="catPoint" />
        <aop:around method="around" pointcut-ref="catPoint" />
    </aop:aspect>
</aop:config>

🌿 aspectj表达式

🌹 execution - 匹配什么

语法如下

//     返回值  匹配的包、类、方法、参数
execution(*   com.sample.service.impl..*.*(..))

支持的匹配符号如下

  • * - 表示任意
  • .- 表示一层包
  • .. - 表示多层包或者任意参数
🌷 @args - 把method参数传给advice

使用如下

@Before("catPoint() && args(tool) && @annotation(anno)")
public void beforeFish(String tool, CatAnno anno) {
    System.out.println("before  - Cat在准备装备!!! -- " + tool + "-----" + 	anno.values().toString());
}

🌼 @annotation- 把注解传给advice
 @Before("catPoint() && args(tool) && @annotation(anno)")
public void beforeFish(String tool, CatAnno anno) {
    System.out.println("before  - Cat在准备装备!!! -- " + tool + "-----" + anno.values().toString());
}

🍖参考

🍖 Aspect Oriented Programming with Spring

🍖 AspectJ切点表达式

📂 笔记 🔖 代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值