美文网首页程序员
Spring Aop实现

Spring Aop实现

作者: 凡哥爱丽姐 | 来源:发表于2020-08-31 20:11 被阅读0次

1、Spring中使用Aop

项目配置

1.1、添加所需的jar包

   <!--springAop开发必须加入的包-->
   <dependency>
            <groupId>aopalliance</groupId>
            <artifactId>aopalliance</artifactId>
            <version>1.0</version>
   </dependency>

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

   <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.0.8.RELEASE</version>
   </dependency>

   <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.0.8.RELEASE</version>
    </dependency>
    <!--springIOC开发必须加入的包-->
    <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.0.8.RELEASE</version>
    </dependency>

    <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.8.RELEASE</version>
     </dependency>
     <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.0.8.RELEASE</version>
     </dependency>

     <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>5.0.8.RELEASE</version>
     </dependency>
     <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>5.0.8.RELEASE</version>
     </dependency>

1.2、添加Aop命名空间(即在applicationContext.xml中加入)

xmlns:aop="http://www.springframework.org/schema/aop"
 http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop/spring-aop.xsd

1.3、创建UserDao接口和接口实现类

package com.fan.dao;

public interface UserDao {
    public void Jianqian();
}
package com.fan.dao.Impl;

import com.fan.dao.UserDao;

public class UserDaoImpl implements UserDao {
    public void Jianqian() {
        System.out.println("借钱");
    }
}

1.4、创建Aop工具类

package com.fan.util;

public class Aop {
    //前置增强方法(前置增强:在目标方法执行之前调取方法)
    public void before(){
        System.out.println("method-before");
    }
    //后置方法
    public void after(){
        System.out.println("method-after");
    }
}

1.5、在applicationContext.xml配置

    <!--1、创建目标类对象-->
    <bean name="D" class="com.fan.dao.Impl.UserDaoImpl"></bean>
    <!--2、配置增强类对象-->
    <bean name="MyAop" class="com.fan.util.Aop"></bean>
    <!--3、将目标方法和增强类建立关系-->
   <!--配置将增强织入到目标对象中-->
    <aop:config>
        <!--pointcut 切入点   expression表达式 execution(被增强的方法)-->
        <aop:pointcut id="mypc" expression="execution(public void Jianqian())"></aop:pointcut>

        <!--指定增强类型-->
        <aop:aspect ref="MyAop">
            <aop:before method="before" pointcut-ref="mypc"></aop:before><!--前置增强-->
        </aop:aspect>
    </aop:config>

1.6、测试类

import com.fan.dao.UserDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test1 {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao =( UserDao)applicationContext.getBean("D");
        userDao.Jianqian();
    }
}
测试结果如下图所示
测试结果

2、增强方法配置

2.1、增强类

//前置通知:目标方法运行之前调用 aop:before
//后置通知(如果出现异常不会调用):在目标方法运行之后调用 aop:after-returning
//环绕通知:在目标方法之前和之后都调用 aop:around
//最终通知(无论是否出现 异常都会调用):在目标方法运行之后调用 aop:after
//异常增强:程序出现异常时执行(要求:程序代码中不要处理异常) aop:after-throwing

2.2、前置增强(上文演示的)

<aop:before method="before" pointcut-ref="mypc"></aop:before><!--前置增强-->

2.3、后置增强

 <aop:after-returning method="after" pointcut-ref="mypc"></aop:after-returning><!--后置增强-->

2.4、环绕增强

Aop工具类中的方法
//环绕增强=前置+后置
    public void myaround(ProceedingJoinPoint joinPoint){
        System.out.println("环绕开始!");
        try {
            joinPoint.proceed();//执行目标方法
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println("环绕结束!");
    }
配置文件中的
<aop:around method="myaround" pointcut-ref="mypc"></aop:around><!--环绕增强-->

2.5、最终增强

Aop工具类中的方法
    //最终增强
    public void afterAll(){
        System.out.println("最终增强(无论是否有异常都会执行)");
    }
配置文件中的
 <aop:after method="afterAll" pointcut-ref="mypc"></aop:after>

2.5、异常增强

Aop工具类中的方法
    //异常增强
    public void myException(){
        System.out.println("异常增强");
    }
配置文件中的
 <aop:after-throwing method="myException" pointcut-ref="mypc"></aop:after-throwing>

3、切入点方法的定义:

表达式匹配规则举例:
public * addUser(com.pb.entity.User):“*”表示匹配所有类型的返回值。
    示例:
    public int addUser(User u);
    public String addUser(User u);
public void * (com.pb.entity.User):“ * ”表示匹配所有方法名。
    示例:
    public void selectUser(User u);
    public void a(User u);
public void addUser (..):“..”表示匹配所有参数个数和类型。
    示例:
    public void addUser(int a)
    public void addUser(int b,int c)
* com.pb.service. *. * (..):匹配com.pb.service 包下所有类的所有方法。
    示例:
    public void com.pb.service.A.a();
    public String com.pb.service.B.a();
* com.pb.service..*(..):匹配com.pb.service 包及子包下所有类的所有方法

4、使用AspectJ依赖注解开发增强方法

4.1、在applicationContext.xml配置文件中添加context约束(增强类也要创建对象)

 xmlns:context="http://www.springframework.org/schema/context"
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context.xsd
    启动扫描Spring注解的代码包(这是用来扫描IOC注解的)
<!--扫描包设置-->
<context:component-scan base-package="com"></context:component-scan>

4.2、在applicationContext.xml配置文件中添加aop约束

xmlns:aop="http://www.springframework.org/schema/aop"
 http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop/spring-aop.xsd
    除了启动Spring注解之外,还要启动aspectJ注解方式
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

4.3、UserDao接口和接口实现类

package com.fan.dao;

public interface UserDao {
    public void Jianqian();
}
package com.fan.dao.Impl;

import com.fan.dao.UserDao;
import org.springframework.stereotype.Component;

@Component
public class UserDaoImpl implements UserDao {
    public void Jianqian() {
        System.out.println("借钱");
    }
}

4.4、Aop工具类

package com.fan.util;

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

@Component
@Aspect
public class Aop {
    //定义一个任意方法
    @Pointcut("execution(public void Jianqian() )")
    public void anyMethod(){

    }

    //前置增强方法(前置增强:在目标方法执行之前调取方法)
    @Before("anyMethod()")
    public void before(){
        System.out.println("method-before");
    }

    //后置方法
    @AfterReturning("anyMethod()")
    public void after(){
        System.out.println("method-after");
    }

    //环绕增强=前置+后置
    @Around("anyMethod()")
    public void myaround(ProceedingJoinPoint joinPoint){
        System.out.println("环绕开始!");
        try {
            joinPoint.proceed();//执行目标方法
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println("环绕结束!");
    }

    //最终增强
    @After("anyMethod()")
    public void afterAll(){
        System.out.println("最终增强(无论是否有异常都会执行)");
    }

    //异常增强
    @AfterThrowing("anyMethod()")
    public void myException(){
        System.out.println("异常增强");
    }
}

@Component
@Aspect
public class MyAop {

    //前置增强
    @Before("execution( public void Jianqian())")
    public void before(){
        System.out.println("前置增加");
    }

    //后置增强
    @AfterReturning("execution( public void Jianqian())")
    public void after(){
        System.out.println("后置增加");
    }
}

4.5、测试类

import com.fan.dao.UserDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test2 {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao =(UserDao) applicationContext.getBean("userDaoImpl");
        userDao.Jianqian();
    }
}

测试结果如下:

测试结果

4.6、注解方式中注解的顺序问题 注解方式的执行顺序

相关文章

  • Spring AOP源码02 - 代理的创建

    Spring AOP 的实现 Spring AOP 不同于 AspectJ 的 AOP 实现,是在 runtime...

  • spring-aop

    aop概念aop概念aop术语AOP实现方式1、spring-aop(使用xml文件实现AOP)2、AspectJ...

  • Spring之AOP面向切面编程

    十、AOP面向切面编程 目录:什么是AOP、AOP在Spring中的作用、Spring实现AOP 1.什么是AOP...

  • Spring Aop、拦截器、过滤器的区别

    Spring AOP Spring AOP,是AOP的一种实现,使用的是代理模式。 Filter Filter(过...

  • Spring

    Spring的aop怎么实现,Spring的aop有哪些实现方式 AOP常用的实现方式有两种,一种是采用声明的方式...

  • [java][SpringAOP]

    为什么会有AOP 实现AOP原理 AOP通知类型 AOP在Spring中配置

  • Spring AOP 实现原理

    Spring AOP 实现原理 静态代理 众所周知 Spring 的 AOP 是基于动态代理实现的,谈到动态代理就...

  • Spring(3)——AOP

    Spring学习总结——Spring实现AOP的多种方式

  • Spring一般切面

    Spring一般切面 Spring 实现了AOP联盟Advice这个接口=>org.aopalliance.aop...

  • Spring 学习--AOP

    参考文献:深入浅析Spring 的aop实现原理Spring AOP 深入剖析AOP: 面向切面编程oop是从上往...

网友评论

    本文标题:Spring Aop实现

    本文链接:https://www.haomeiwen.com/subject/ppgfahtx.html