SpringAOP的三种实现方式总结

SpringAOP的实现方式

1.使用原生SpringApi接口实现AOP:

  • 首先咱们写个UserService接口和它的实现类java

    public interface UserService {
        public void add();
    }
    
    public class UserServiceImpl implements UserService {
        @Override
        public void add() {
            System.out.println("add user");
        }
    }
  • 在applicationConte.xml导入命名空间。先搞切入点,再在切入点把Log.java切入进去。spring

<bean id="userService" class="com.zhou.service.UserServiceImpl"/>
    <bean id="log" class="com.zhou.log.Log"/>
    <bean id="afterLog" class="com.zhou.log.AfterLog"/>
<!--    方式一:执行原生SpringApi接口-->
    <aop:config>
<!--        切入点 execution(第一个“*”表示返回值的类型任意 “com.zhou.service.UserServiceImpl”要执行的位置  “.*” 表明这个类下的全部方法  “..”表明能够有任意参数) -->
        <aop:pointcut id="pointcut" expression="execution(* com.zhou.service.UserServiceImpl.*(..))"/>

<!--        执行环绕!  把log这个类切入到“* com.zhou.service.UserServiceImpl.*(..)”方法上面-->
        <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
        <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
    </aop:config>
  • 前置和后置的Log
Log.java:
public class Log implements MethodBeforeAdvice {
    // method:方法
    //objects:参数
    //o:对象
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println(o.getClass().getName()+"的"+method.getName()+"被执行了");//某某对象的方法被执行了
    }
}


AfterLog.java:    
package com.zhou.log;

public class AfterLog implements AfterReturningAdvice {
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] objects, Object target) throws Throwable {
        System.out.println("执行了"+method.getName()+"返回的结果为"+returnValue);
    }
}
  • 测试代码以下
public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //PS:动态代理的是接口
        UserService userService = (UserService) context.getBean("userService");
        userService.add();
    }
    //报错了 由于没导入aspect依赖
}
  • 输出结果

com.zhou.service.UserServiceImpl的add被执行了
add user
执行了add返回的结果为nullexpress

2.自定义类实现AOP

  • 先写一个简单MyPointCut类api

    public class MyPointCut {
    
        public void before(){
            System.out.println("我在方法执行前面");
        }
    
        public void after(){
            System.out.println("我在方法执行后面");
        }
    }
  • 另外一种方式配置applicationConte.xmlapp

    <!--方式二:自定义类-->
        <bean id="diyPointCut" class="com.zhou.own.MyPointCut"/>
        <aop:config>
    <!--自定义切面 -->
            <aop:aspect ref="diyPointCut">
    <!--切入点-->
            <aop:pointcut id="pointcut" expression="execution(* com.zhou.service.UserServiceImpl.*(..))"/>
    <!-- 通知-->
                <aop:before method="before" pointcut-ref="pointcut"/>
                <aop:after method="after" pointcut-ref="pointcut"/>
            </aop:aspect>
        </aop:config>
  • 测试一下ide

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

    输出结果:测试

    ​ 我在方法执行前面
    ​ add user
    ​ 我在方法执行后面代理

  • execution表达式:code

    <aop:pointcut id="pointcut" expression="execution(* com.zhou.service.UserServiceImpl.*(..))"/>
    * 表示返回值的类型任意
    com.zhou.service.UserServiceImpl 横切的业务类路径
    .* 表明这个类下的全部方法
    (..) ()表明参数,两个点表明能够有任意参数

    3.使用注解实现AOP

  • MyPointCut.javaxml

    @Aspect
    public class AnnotationPointCut {
        @Before("execution(* com.zhou.service.UserServiceImpl.*(..))")
        public void before() {
            System.out.println("我在方法执行前面");
        }
    
        @After("execution(* com.zhou.service.UserServiceImpl.*(..))")
        public void after() {
            System.out.println("我在方法执行后面");
        }
  • 关于环绕(@Around)

    //在环绕加强中 咱们能够给定一个参数 表明咱们要处理切入的点 JointPoint:与切入点匹配的执行点
        @Around("execution(* com.zhou.service.UserServiceImpl.*(..))")
        public void around(ProceedingJoinPoint joinPoint) throws Throwable {
            System.out.println("环绕前");
            Object proceed = joinPoint.proceed();//执行方法
            System.out.println("环绕后");
    
            //Signature signature = joinPoint.getSignature();
            //System.out.println("signature:" + signature.toString());
        }
    }
  • 配置文件

    <!--    方式三-->
        <bean id="annotationPointCut" class="com.zhou.own.AnnotationPointCut"/>
    <!--    开启注解支持-->
        <aop:aspectj-autoproxy/>
  • 输出结果:看看顺序= =

    环绕前 我在方法执行前面 add user 我在方法执行后面 环绕后

相关文章
相关标签/搜索