Java练习(十九):编写代码,实现AOP的@Around操作 (两种写法)

目录

1. 要求

2. 涉及的知识点

3. 示例工程 (第一种方式)

3.1 maven的配置文件: pom.xml 

3.2 bean配置文件: bean_aop_around.xml

3.3 接口和类的代码

3.3.1 接口:UserService

3.3.2 实现接口的类:UserServiceImpl

3.3.3 AroundLog类:AroundLog

3.4 测试类 

4. 示例工程(第二种方式)

4.1 maven的配置文件: pom.xml 

4.2 bean配置文件: bean_aop_around2.xml

4.3 接口和类的代码

4.3.1 接口:UserService

4.3.2 实现接口的类:UserServiceImpl

4.3.3 AnnotationPointcut类:

4.4 测试类 


1. 要求

之前完成了通过@Before@After的方式,完成了对类UserServiceImpl中的search方法的aop操作 ,这里要求:通过@Aspect注解的方式实现对UserServiceImpl的aop的@Around操作!

前文:

Java练习(十):Spring应用之AOP的@Before, @After操作(简单工程示例)

2. 涉及的知识点

@Before, @After, @Around三者之前的关系:

@Before 是在所拦截方法执行之前执行一段逻辑。

@After 是在所拦截方法执行之后执行一段逻辑。

@Around 是可以同时在所拦截方法的前后执行一段逻辑。

简言之,@Around就包含了@Before和@After两个操作。

3. 示例工程 (第一种方式)

 

3.1 maven的配置文件: pom.xml 

<?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>org.example</groupId>
    <artifactId>MySpringAOPAround</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.3</version>
        </dependency>

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

        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
        </dependency>

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

    </dependencies>

</project>

3.2 bean配置文件: bean_aop_around.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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       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
        http://www.springframework.org/schema/aop/spring-aop.xsd">

    <context:annotation-config/>

    <!--注册bean-->
    <bean id="userService" class="com.my.spring.aop.around.UserServiceImpl"/>
    <bean id="aroundLog" class="com.my.spring.aop.around.AroundLog"/>
<!--    <bean id="beforeLog" class="com.my.spring.aop.around.BeforeLog"/>-->
<!--    <bean id="afterLog" class="com.my.spring.aop.around.AfterLog"/>-->

    <!--aop的配置-->
    <aop:config>
        <!--切入点 expression:表达式匹配要执行的方法-->
        <aop:pointcut id="pointcut" expression="execution(* com.my.spring.aop.around.UserServiceImpl.*(..))"/>
        <aop:advisor advice-ref="aroundLog" pointcut-ref="pointcut"/>
<!--        <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>-->
<!--        <aop:advisor advice-ref="beforeLog" pointcut-ref="pointcut"/>-->
    </aop:config>

</beans>


3.3 接口和类的代码

3.3.1 接口:UserService

package com.my.spring.aop.around;

public interface UserService {
    public void add();
    public void delete();
    public void update();
    public void search();
}

3.3.2 实现接口的类:UserServiceImpl

package com.my.spring.aop.around;

public class UserServiceImpl implements UserService{
    public void add() {
        System.out.println("增加用户");
    }
    public void delete() {
        System.out.println("删除用户");
    }
    public void update() {
        System.out.println("更新用户");
    }
    public void search() {
        System.out.println("查询用户");
    }
}

3.3.3 AroundLog类:AroundLog

package com.my.spring.aop.around;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class AroundLog implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        String name = invocation.getMethod().getName();
        System.out.println("环绕通知: " + name + "方法即将开始!");
        // 调用目标对象的指定方法
        //真正调用目标方法
        Object result = invocation.proceed();
        System.out.println("环绕通知: " + name + "方法到此结束!");
        return result;
    }
}

3.4 测试类 

package com.my.spring.around.demo;

import com.my.spring.aop.around.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MySpringAOPAroundTest {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean_aop_around.xml");
        UserService userService = (UserService) context.getBean("userService");
        userService.search();
    }

}

输出结果:

环绕通知: search方法即将开始!
查询用户
环绕通知: search方法到此结束!

4. 示例工程(第二种方式)

用注解标签 @Aspect, @Around。

简言之,就是简化了bean配置文件里的内容,设置语句<aop:aspectj-autoproxy/>自动扫描,在工程中自动查找标签 @Aspect, @Around等。

4.1 maven的配置文件: pom.xml

同3.1,这里不赘述。

4.2 bean配置文件: bean_aop_around2.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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       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
        http://www.springframework.org/schema/aop/spring-aop.xsd">

    <context:annotation-config/>
    <!--注册bean-->
    <bean id="annotationPointcut" class="com.my.spring.aop.around.AnnotationPointcut"/>
    <bean id="userService2" class="com.my.spring.aop.around.UserServiceImpl"/>

    <!-- 简化了bean配置文件里的内容,设置语句<aop:aspectj-autoproxy/>自动扫描 -->
    <aop:aspectj-autoproxy/>

</beans>

4.3 接口和类的代码

4.3.1 接口:UserService

package com.my.spring.aop.around;

public interface UserService {
    public void add();
    public void delete();
    public void update();
    public void search();
}

4.3.2 实现接口的类:UserServiceImpl

package com.my.spring.aop.around;

public class UserServiceImpl implements UserService{
    public void add() {
        System.out.println("增加用户2");
    }
    public void delete() {
        System.out.println("删除用户2");
    }
    public void update() {
        System.out.println("更新用户2");
    }
    public void search() {
        System.out.println("查询用户2");
    }
}

4.3.3 AnnotationPointcut类:

类似于第一种方法中的AroundLog类,实现环绕效果,方法的调用。

使用注解@Aspect, @Around。

package com.my.spring.aop.around;

// 如果自动扫描<aop:aspectj-autoproxy/>,那么程序肯定找标签
// 在整个工程里找标签,即如果包含多个类文件,多个@Aspect,程序都会找到并执行。
// 但真实的情况下,同一个方法,不会用多个@Around

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class AnnotationPointcut {
    /*
    @Before("execution(*  com.my.demo.aop.UserServiceImpl.*(..))")
      public void before(){
          System.out.println("---------方法执行前---------");
     }

      @After("execution(* com.my.demo.aop.UserServiceImpl.*(..))")
      public void after(){
          System.out.println("---------方法执行后---------");
     }
     */

    @Around("execution(* com.my.spring.aop.around.UserServiceImpl.*(..))")
    public void around(ProceedingJoinPoint jp) throws Throwable{
        System.out.println("~~~~~~~~~~~~~~~~Around方法执行前~~~~~~~~~~~~~~~~~~~~~");
        System.out.println("签名: "+jp.getSignature());
        Object proceed = jp.proceed(); //执行目标方法
        System.out.println("~~~~~~~~~~~~~~~~Around方法执行后~~~~~~~~~~~~~~~~~~~~~");
    }
}

4.4 测试类 

package com.my.spring.around.demo;

import com.my.spring.aop.around.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MySpringAOPAroundTest2 {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean_aop_around2.xml");
        UserService userService = (UserService) context.getBean("userService2");
        userService.search();
    }
}

输出结果:

~~~~~~~~~~~~~~~~Around方法执行前~~~~~~~~~~~~~~~~~~~~~
签名: void com.my.spring.aop.around.UserService.search()
查询用户2
~~~~~~~~~~~~~~~~Around方法执行后~~~~~~~~~~~~~~~~~~~~~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值