Spring入门知识 ———— 实现AOP前置通知以及后置通知

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_38111957/article/details/83715587

一、引言

什么是前置通知和后置通知?

前置通知:调用方法之前,后置通知:调用方法之后。

那比如之前实现的日志记录功能,都是在调用方法之前记录的日志,AOP可以很灵活的控制,切点在什么时候执行。

二、功能需求

还是拿我们之前代理那一章节中的例子。有一个针对用户的增删改查的方法,需要做日志记录。

public interface UserMange {

    void insertUser(String username, String password);

    String findUser(Integer id);

    void deleteUser(Integer id);

    void update(String username, String password, Integer id);
}
import org.springframework.stereotype.Service;

@Service
public class UserMangeImpl implements UserMange {

    public void insertUser(String username, String password) {
        System.out.println("----------UserMangeImpl.insertUser-----------");
    }

    public String findUser(Integer id) {
        System.out.println("----------UserMangeImpl.findUser-----------");
        return "张山";
    }

    public void deleteUser(Integer id) {
        System.out.println("----------UserMangeImpl.deleteUser-----------");
    }

    public void update(String username, String password, Integer id) {
        System.out.println("----------UserMangeImpl.update-----------");
    }
}

三、使用AOP实现

首先我们先来学习一个采用注解的方式来实现,AspectJ,java社区里面最完整,最流行的AOP框架。

在Spring2.0以上的版本,可以使用基于AspectJ注解或XML配置的AOP。 

先引入AspectJ jar包

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.7.0</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.7.0</version>
        </dependency>
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

/**
 * 定义一个切点
 */
@Aspect
public class InsertLogHeadr {


    /**
     * 定一个Pointcut,此方法没有返回值和参数
     * 该方法就是一个标识,不进行调用
     *
     * execution中解释:
     * 第一个* :表示任意修饰符的方法
     * com.spring.two.UserMangeImpl.* : 具体的类下面全部的方法
     * (..):任意参数列表
     */
    @Pointcut("execution(* com.spring.two.UserMangeImpl.*(..))")
    public void beforLog(){}


    /**
     * 定义Advice,表示应用到那些Pointcut订阅的Joinpoint上
     * Before 调用方法之前
     */
    @Before("beforLog()")
    public void insertLogBefor(){
        System.out.println("InsertLogHeadr.insertLogBefor");
    }

    /**
     * 定义Advice,表示应用到那些Pointcut订阅的Joinpoint上
     * After 调用方法之后
     */
    @After("beforLog()")
    public void insertLogAfter(){
        System.out.println("InsertLogHeadr.insertLogBefor");
    }


}
<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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">

        <!--扫描注解的包-->
       <context:component-scan base-package="com.spring.two"></context:component-scan>

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

       <!--需要定义的切点配置到IOC容器当中-->
       <bean id="InsertLogHeadr" class="com.spring.two.InsertLogHeadr"></bean>
</beans>

最后测试咯:不管调用UserMange中任意一个方法, 都会执行切点中定义的方法。

    public static void main(String[] args) {

        BeanFactory beanFactory = new ClassPathXmlApplicationContext("applicationContext-two.xml");
        UserMange userMange = (UserMange)beanFactory.getBean("userMangeImpl");
        userMange.findUser(1);
    }
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
InsertLogHeadr.insertLogBefor
----------UserMangeImpl.findUser-----------
InsertLogHeadr.insertLogAfter

Process finished with exit code 0

猜你喜欢

转载自blog.csdn.net/weixin_38111957/article/details/83715587