AOP简单相关配置

AOP概念以及作用

在这里插入图片描述
AOP开发思想
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
AOP相关概念
在这里插入图片描述
在这里插入图片描述
AOP开发方式
XML方式
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:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--3.开启AOP命名空间-->
    <bean id="userService" class="com.itheima.service.impl.UserServiceImpl"/>
    <!--2.配置共性功能成功spring控制的资源-->
    <bean id="myAdvice" class="com.itheima.aop.AOPAdvice"/>

<!--4 配置AOP-->
    <aop:config>
        <!--5.配置切入点-->
        <aop:pointcut id="pt" expression="execution(* *..*(..))"/>

        <!--6.配置切面(切入点与通知的关系)-->
        <aop:aspect ref="myAdvice">
            <!--7.配置具体的切入点对应通知中那个操作方法-->
            <aop:before method="function" pointcut-ref="pt"/>
        </aop:aspect>
    </aop:config>
</beans>

在这里插入图片描述

package com.itheima.service.impl;

import com.itheima.service.UserService;

public class UserServiceImpl implements UserService {
    public void save() {

        /// 0 将共性功能突出出来
        //System.out.println("共性功能");
        System.out.println("user servoce running ...");
    }
}
package com.itheima.service;

public interface UserService {
    void save();
}

在这里插入图片描述

package com.itheima.aop;

///1 制作通知类,在类中定义一个方法用于完全共性功能
public class AOPAdvice {
    public void function() {
        System.out.println("共性功能");
    }
}

在这里插入图片描述

import com.itheima.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    public static void main(String[] args) {
        ApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) classPathXmlApplicationContext.getBean("userService");
        userService.save();
    }
}

AOP配置(XML)
AspectJ
Aspect(切面)用于描述切入点与通知间的关系,是AOP编程中的一个概念
AspectJ是基于java语言对Aspect的实现

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

<?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:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--3.开启AOP命名空间-->
    <bean id="userService" class="com.itheima.service.impl.UserServiceImpl"/>
    <!--2.配置共性功能成功spring控制的资源-->
    <bean id="myAdvice" class="com.itheima.aop.AOPAdvice"/>

<!--4 配置AOP-->
<!--    <aop:config>-->
<!--        &lt;!&ndash;5.配置切入点&ndash;&gt;-->
<!--        <aop:pointcut id="pt" expression="execution(* *..*(..))"/>-->

<!--        &lt;!&ndash;6.配置切面(切入点与通知的关系)&ndash;&gt;-->
<!--        <aop:aspect ref="myAdvice">-->
<!--            &lt;!&ndash;7.配置具体的切入点对应通知中那个操作方法&ndash;&gt;-->
<!--            <aop:before method="before" pointcut-ref="pt"/>-->
<!--        </aop:aspect>-->
<!--    </aop:config>-->

<!--    &lt;!&ndash;4 配置AOP&ndash;&gt;-->
<!--    <aop:config>-->
<!--        &lt;!&ndash;5.配置切入点&ndash;&gt;-->
<!--        <aop:pointcut id="pt" expression="execution(* *..*(..))"/>-->

<!--        &lt;!&ndash;6.配置切面(切入点与通知的关系)&ndash;&gt;-->
<!--        <aop:aspect ref="myAdvice">-->
<!--            &lt;!&ndash;7.配置具体的切入点对应通知中那个操作方法&ndash;&gt;-->
<!--            <aop:before method="before" pointcut-ref="pt"/>-->
<!--        </aop:aspect>-->

<!--        &lt;!&ndash;6.配置切面(切入点与通知的关系)&ndash;&gt;-->
<!--        <aop:aspect ref="myAdvice">-->
<!--            &lt;!&ndash;7.配置具体的切入点对应通知中那个操作方法&ndash;&gt;-->
<!--            <aop:before method="before" pointcut-ref="pt"/>-->
<!--        </aop:aspect>-->

<!--    </aop:config>-->

    <!--4 配置AOP-->
    <aop:config>
        <!--5.配置切入点-->
        <aop:pointcut id="pt" expression="execution(* *..*(..))"/>
        <aop:pointcut id="pt2" expression="execution(* *..*(..))"/>
        <!--6.配置切面(切入点与通知的关系)-->
        <aop:aspect ref="myAdvice">
            <!--7.配置具体的切入点对应通知中那个操作方法-->
            <aop:before method="before" pointcut-ref="pt2"/>
        </aop:aspect>

    </aop:config>
</beans>

切入点

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

    <!--4 配置AOP-->
    <aop:config>
        <!--5.配置切入点-->
<!--        <aop:pointcut id="pt" expression="execution(* *..save(..))"/>-->
<!--        无参-->
<!--        <aop:pointcut id="pt" expression="execution(* *..save())"/>-->
<!--        带*代表着带一个参数-->
<!--        <aop:pointcut id="pt" expression="execution(* *..save(*))"/>-->
<!--        <aop:pointcut id="pt" expression="execution(* com.itheima.service.impl.UserServiceImpl.save(..))"/>-->
        <!--任意包下的-->
<!--        <aop:pointcut id="pt" expression="execution(* com.itheima..UserServiceImpl.save(..))"/>-->
        <!--接口能用 前提必须要接口定义-->
        <aop:pointcut id="pt" expression="execution(* com..UserService.save(..))"/>
        <!--6.配置切面(切入点与通知的关系)-->
        <aop:aspect ref="myAdvice">
            <!--7.配置具体的切入点对应通知中那个操作方法-->
            <aop:before method="before" pointcut-ref="pt"/>
        </aop:aspect>

    </aop:config>
</beans>

切入点的三种配置方式
在这里插入图片描述

    <aop:config>
        <!--公共切入点-->
        <aop:pointcut id="pt" expression="execution(* com..UserService.save(..))"/>
        <!--6.配置切面(切入点与通知的关系)-->
        <aop:aspect ref="myAdvice">
            <!--局部切入点-->
            <aop:pointcut id="pt2" expression="execution(* com..UserService.save(..))"/>
            <!--7.配置具体的切入点对应通知中那个操作方法-->
<!--            <aop:before method="before" pointcut-ref="pt2"/>-->
        <!--直接配置切入点-->
            <aop:before method="before" pointcut="execution(* com..UserService.save(..))"/>
        </aop:aspect>

    </aop:config>

在这里插入图片描述
五个通知类型
在这里插入图片描述
在这里插入图片描述

    <aop:config>
        <!--公共切入点-->
        <aop:pointcut id="pt" expression="execution(* com..UserService.save(..))"/>
        <!--6.配置切面(切入点与通知的关系)-->
        <aop:aspect ref="myAdvice">
            <!--7.配置具体的切入点对应通知中那个操作方法-->
<!--            <aop:before method="before" pointcut-ref="pt"/>-->
            <!--后置通知-->
<!--            <aop:after method="after" pointcut-ref="pt"/>-->
<!--            返回后通知,如果抛出异常以后,无法执行-->
<!--            <aop:after-returning method="afterThrowing" pointcut-ref="pt"/>-->
<!--           抛出异常后通知-->
<!--            <aop:after-throwing method="afterThrowing" pointcut-ref="pt"/>-->
            <aop:around method="around" pointcut-ref="pt"/>
        </aop:aspect>

    </aop:config>

在这里插入图片描述

package com.itheima.aop;

import org.aspectj.lang.ProceedingJoinPoint;

///1 制作通知类,在类中定义一个方法用于完全共性功能
public class AOPAdvice {
    public void function() {
        System.out.println("共性功能");
    }

    ///前置通知
    public void before() {
        System.out.println("before");
    }
    /// 后置通知
    public void after() {
        System.out.println("after");
    }
    /// 返回后通知
    public void afterReturing() {
        System.out.println("afterReturing");
    }
    /// 抛出异常后通知
    public void afterThrowing() {
        System.out.println("afterThrowing");
    }
    /// 环绕通知
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("around before");
        /// 对原始方法的调用
        proceedingJoinPoint.proceed();
        System.out.println("around after");
    }


}

通知顺序(了解)
在这里插入图片描述
通知获取参数数据
在这里插入图片描述
在这里插入图片描述

    <aop:config>
        <!--公共切入点-->
        <aop:pointcut id="pt" expression="execution(* *..*(..))"/>
        <!--6.配置切面(切入点与通知的关系)-->
        <aop:aspect ref="myAdvice">
            <!--7.配置具体的切入点对应通知中那个操作方法-->
<!--            <aop:before method="before" pointcut-ref="pt"/>-->
            <aop:before method="before" pointcut="execution(* *..*(int)) &amp;&amp; args(x)"/>
            <!--后置通知-->
            <aop:after method="after" pointcut-ref="pt"/>
        </aop:aspect>

    </aop:config>

在这里插入图片描述
在这里插入图片描述

package com.itheima.aop;

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

///1 制作通知类,在类中定义一个方法用于完全共性功能
public class AOPAdvice {
    public void function() {
        System.out.println("共性功能");
    }

    ///前置通知
//    public void before(JoinPoint joinPoint) {
//        Object[] args = joinPoint.getArgs();
//        System.out.println("before..."+args[0]);
//    }
    public void before(int x) {

        System.out.println("before(int)..."+x);
    }

    /// 后置通知
    public void after(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        System.out.println("after..."+args[0]);
    }


}

通知获取返回值数据
在这里插入图片描述

  <aop:config>
        <!--公共切入点-->
        <aop:pointcut id="pt" expression="execution(* *..*(..))"/>
        <!--6.配置切面(切入点与通知的关系)-->
        <aop:aspect ref="myAdvice">
            <!--7.配置具体的切入点对应通知中那个操作方法-->
            <!--            返回后通知,如果抛出异常以后,无法执行-->
            <aop:after-returning method="afterReturing" pointcut-ref="pt" returning="ret"/>

            <aop:around method="around" pointcut-ref="pt"/>
        </aop:aspect>

    </aop:config>

在这里插入图片描述

 /// 返回后通知
    public void afterReturing(Object ret) {
        System.out.println("afterReturing..." +
                "" +
                ""+ret);
    }
    /// 抛出异常后通知
    public void afterThrowing() {
        System.out.println("afterThrowing");
    }
    /// 环绕通知
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("around before");
        /// 对原始方法的调用
        Object ret = proceedingJoinPoint.proceed();
        System.out.println("around after..."+ret);
        //如果是void 必须这里return null
        return ret;
    }

通知获取异常数据
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

        <aop:config>
            <!--公共切入点-->
            <aop:pointcut id="pt" expression="execution(* *..*(..))"/>
            <!--6.配置切面(切入点与通知的关系)-->
            <aop:aspect ref="myAdvice">
<!--                <aop:after-throwing method="afterThrowing" pointcut-ref="pt" throwing="throwable"/>-->
                <aop:around method="around" pointcut-ref="pt"/>
            </aop:aspect>

        </aop:config>

在这里插入图片描述

 /// 抛出异常后通知
    public void afterThrowing(Throwable throwable) {
        System.out.println("afterThrowing..."+throwable.getMessage());
    }
    /// 环绕通知
    public Object around(ProceedingJoinPoint proceedingJoinPoint) {
        System.out.println("around before");
        /// 对原始方法的调用
        Object ret = null;
        try{
            ret = proceedingJoinPoint.proceed();
        } catch (Throwable throwable) {
            System.out.println("around...exception..."+throwable.getMessage());
        }
        System.out.println("around after..."+ret);
        //如果是void 必须这里return null
        return ret;
    }

App入口
在这里插入图片描述

import com.itheima.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    public static void main(String[] args) {
        ApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) classPathXmlApplicationContext.getBean("userService");
//        userService.save(666);
//        int ret = userService.update();
//        System.out.println("app ...."+ret);
        userService.delete();

    }
}

AOP配置 注解模式
在这里插入图片描述

@Pointcut 可以配置在变量上,但是会分配内存空间,相对于定义方法来说,定义方法,定义内存泄漏。

在这里插入图片描述
在这里插入图片描述

<?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:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--磁盘扫描-->
    <context:component-scan base-package="com.itheima"/>
    <!--开启aop注解支持-->
    <aop:aspectj-autoproxy/>
</beans>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

import com.itheima.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) ctx.getBean("userService");
        userService.save(666,888);
    }
}
package com.itheima.service.impl;

import com.itheima.service.UserService;
import org.springframework.stereotype.Service;

@Service("userService")
public class UserServiceImpl implements UserService {

    public int save(int i, int m) {

        System.out.println("user service running ..."+i+","+m);
        return 100;
    }
}
package com.itheima.aop;

import org.aspectj.lang.annotation.Pointcut;

public class AOPPointcut {
    @Pointcut("execution(* *..*(..))")
    public void pt1(){}
}
package com.itheima.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

///1 制作通知类,在类中定义一个方法用于完全共性功能
@Component
@Aspect
public class AOPAdvice {

//    @Pointcut("execution(* *..*(..))")
//    public void pt(){}

    @Before("AOPPointcut.pt1()")
    public void before() {

        System.out.println("before(int)...");
    }

    /// 后置通知
    @After("AOPPointcut.pt1()")
    public void after() {
        System.out.println("after...");

    }
    /// 返回后通知
    @AfterReturning("AOPPointcut.pt1()")
    public void afterReturing() {
        System.out.println("afterReturing");
    }

    /// 抛出异常后通知
    @AfterThrowing("AOPPointcut.pt1()")
    public void afterThrowing() {
        System.out.println("afterThrowing...");
    }

    /// 环绕通知
    @Around("AOPPointcut.pt1()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("around before");
        /// 对原始方法的调用
        Object ret = proceedingJoinPoint.proceed();;
        System.out.println("around after...");
        //如果是void 必须这里return null
        return ret;
    }


}

AOP注解开发通知执行顺序控制
在这里插入图片描述
在这里插入图片描述
AOP注解驱动
在这里插入图片描述
在这里插入图片描述

package com.itheima.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@ComponentScan("com.itheima")
@EnableAspectJAutoProxy
public class SpringConfig {
}

在这里插入图片描述
@Autowired
@Autowired
private UserService userService; 这个id是通过 @Service(“userService”)查找
在这里插入图片描述

package com.itheima.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@ComponentScan("com.itheima")
@EnableAspectJAutoProxy
public class SpringConfig {
}
package com.itheima.service;

import com.itheima.config.SpringConfig;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class UserServiceTest {

    @Autowired
    private UserService userService;

    @Test
    public void testSave() {
        int ret = userService.save(888,666);
        Assert.assertEquals(100,ret);
    }
}
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>Spring_AOP综合案例</groupId>
  <artifactId>Spring_AOP综合案例</artifactId>
  <version>1.0-SNAPSHOT</version>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.1.9.RELEASE</version>
    </dependency>

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

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.47</version>
    </dependency>

    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.16</version>
    </dependency>

    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.3</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.1.9.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.3.0</version>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>5.1.9.RELEASE</version>
    </dependency>

  </dependencies>

</project>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Spring AOP 中,配置上下文可以通过以下步骤完成: 1. 在 Spring 配置文件中引入 aop 命名空间,如下所示: ```xml <beans xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> ``` 2. 定义切面类,其中包含切点和通知的定义。例如,创建一个名为 `LoggingAspect` 的切面类: ```java public class LoggingAspect { // 定义切点 @Pointcut("execution(* com.example.service.*.*(..))") private void serviceMethods() {} // 定义前置通知 @Before("serviceMethods()") public void beforeAdvice() { System.out.println("Before advice executed!"); } // 定义后置通知 @After("serviceMethods()") public void afterAdvice() { System.out.println("After advice executed!"); } } ``` 3. 在 Spring 配置文件中配置切面类的 bean: ```xml <bean id="loggingAspect" class="com.example.aspect.LoggingAspect" /> ``` 4. 配置 AOP 代理,将切面应用到目标对象上。可以使用 `<aop:config>` 元素来配置代理。例如: ```xml <aop:config> <aop:aspect ref="loggingAspect"> <aop:before method="beforeAdvice" pointcut-ref="serviceMethods" /> <aop:after method="afterAdvice" pointcut-ref="serviceMethods" /> </aop:aspect> </aop:config> ``` 在上述配置中,`ref` 属性指定了切面类的 bean ID,`method` 属性指定了通知方法的名称,`pointcut-ref` 属性指定了切点的引用。 通过以上配置,你可以在目标对象的方法执行前后执行相应的通知方法。注意,上述示例中的切点表达式是一个简单的示例,你需要根据实际情况进行调整。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值