Spring AOP的实现

一、介绍

AOP 面向切面编程,可以在不修改现有代码的情况下,对程序的功能进行拓展,,主要可以用来权限控制,性能检测,事务控制。

AOP实现的原理就是动态代理,在有接口的情况下,使用JDK动态代理,在没有接口的情况下使用cglib动态代理

二、AOP术语

2.1 连接点 (Join Point)

主要是指可以被增强的方法

2.2 切入点 (PointCut)

实际上被增强的方法

2.3 通知(advice)

实际增强的功能

2.4 目标对象(Target)

被增强功能的对象(被代理的对象)

2.5 切面(Aspect)

表现为功能相关的一些advice方法放在一起声明成的一个Java类 

2.6 织入(Weaving)

创建代理对象并实现功能增强的声明并运行过程 

三、aop注解方式实现

3.1 引入相关依赖

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

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

    <!--spring 切面包-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>5.3.25</version>
    </dependency>

    <!--aop联盟-->
    <dependency>
        <groupId>aopalliance</groupId>
        <artifactId>aopalliance</artifactId>
        <version>1.0</version>
    </dependency>
</dependencies>

3.2 建立UserDao接口和实现类

public interface UserDao {

    public int addUser(Integer id,String name);
}
@Repository
public class UserDaoImpl implements UserDao {
    public int addUser(Integer id, String name) {
        System.out.println(id+","+name);
        return id;
    }
}

3.3 编写配置文件

<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://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">


    <!--spring包扫描-->
    <context:component-scan base-package="com.msb.aop"/>
    <!--开启自动代理-->
    <aop:aspectj-autoproxy/>
    
</beans>

3.4 建立DaoAspect类

@Aspect
@Component
public class DaoAspect {

}

3.5 前置通知(在DaoAspect这个类中写对应的方法)

/*
    * 前置通知: 切点方法执行之前先执行的功能
    * 参数列表可以用JoinPoint接收切点对象
    * 可以获取方法执行的参数
    */
    @Before("execution(* com.msb.aop.dao.UserDao.add*(..))")
    public void testBefore(JoinPoint joinPoint){
        System.out.println("before执行");
        System.out.println(joinPoint.getArgs());
        Object target = joinPoint.getTarget();
        System.out.println(target.toString());
    }

3.6 后置通知

/*
       * 后置通知:方法执行之后要增强的功能
       * 无论切点方法是否出现异常都会执行的方法
       * 参数列表可以用JoinPoint接收切点对象
       * */
    @After("execution(* com.msb.aop.dao.UserDao.add*(..))")
    public void testAfter(JoinPoint joinPoint){
        System.out.println("后置通知");
    }

3.7 返回通知

 /*
     * 返回通知:切点方法正常运行结束后增强的功能
     * 如果方法运行过程中出现异常,则该功能不运行
     * 参数列表可以用 JoinPoint joinPoint接收切点对象
     * 可以用Object res接收方法返回值,需要用returning指定返回值名称
     * */
    @AfterReturning(value = "execution(* com.msb.aop.dao.UserDao.addUser(..))",returning = "res")
    public void testAfterReturning(JoinPoint joinPoint,Object res){
        System.out.println("返回通知");
        System.out.println(res);
    }

3.8 异常通知

/*
     * 异常通知:切点方法出现异常时运行的增强功能
     * 如果方法运行没有出现异常,则该功能不运行
     * 参数列表可以用Exception ex接收异常对象 需要通过throwing指定异常名称
     */
    @AfterThrowing(value = "execution(* com.msb.aop.dao.UserDao.addUser(..))",throwing = "ex")
    public void testAfterThrowing(JoinPoint joinPoint,Exception ex){
        System.out.println("异常通知执行");
        System.out.println(ex);
    }

3.9 环绕通知

   /*环绕通知:在切点方法之前和之后都进行功能的增强
    * 需要在通知中定义方法执行的位置,并在执行位置之前和之后自定义增强的功能
    * 方法列表可以通过ProceedingJoinPoint获取执行的切点
    * 我们在环绕通知的最后需要将切点方法的返回值继续向上返回,否则切点方法在执行时接收不到返回值
    * */

    @Around(value = "execution(* com.msb.aop.dao.UserDao.addUser(..))")
    public Object testAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("前");
        Object proceed = proceedingJoinPoint.proceed();
        System.out.println("后");
        return proceed;
    }

3.10 测试方法

    @Test
    public void testBefore(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext-spring.xml");
        UserDao userDao = applicationContext.getBean(UserDao.class);
        userDao.addUser(1,"yanlingfei");
    }

 四、JoinPoint 和 ProceedingJoinPoint

4.1 ProceedingJoinPoint

public interface ProceedingJoinPoint extends JoinPoint {

  
    void set$AroundClosure(AroundClosure arc);

   
    default void stack$AroundClosure(AroundClosure arc) {
    	 throw new UnsupportedOperationException();
    }

   
	Object proceed() throws Throwable;

  
	Object proceed(Object[] args) throws Throwable;

}

4.2 JoinPoint

public interface JoinPoint {

    String toString();

   
    String toShortString();

    String toLongString();

  
    Object getThis();
    
    //  返回目标对象,即被代理的对象
    Object getTarget();

    // 返回切入点的参数
    Object[] getArgs();
    // 返回切入点的Signature
    Signature getSignature();

   
    SourceLocation getSourceLocation();

   
    String getKind();

   
	interface StaticPart {
       
        Signature getSignature();

        SourceLocation getSourceLocation();

        String getKind();

        int getId();

        String toString();

        String toShortString();

        
        String toLongString();
    }

    interface EnclosingStaticPart extends StaticPart {}

   
    StaticPart getStaticPart();


  
	String METHOD_EXECUTION = "method-execution";
    String METHOD_CALL = "method-call";
    String CONSTRUCTOR_EXECUTION = "constructor-execution";
    String CONSTRUCTOR_CALL = "constructor-call";
    String FIELD_GET = "field-get";
    String FIELD_SET = "field-set";
    String STATICINITIALIZATION = "staticinitialization";
    String PREINITIALIZATION = "preinitialization";
    String INITIALIZATION = "initialization";
    String EXCEPTION_HANDLER = "exception-handler";
    String SYNCHRONIZATION_LOCK = "lock";
    String SYNCHRONIZATION_UNLOCK = "unlock";

    String ADVICE_EXECUTION = "adviceexecution";

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值