随笔都是学习笔记
随笔仅供参考,为避免笔记中可能出现的错误误导他人,请勿转载。

 

 

 

上代码:

注入一个Aop切面类:

package cn.cdulm.aspects;

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

import java.util.ArrayList;
import java.util.Arrays;

@Aspect // 标记为切面
@Component  // 标记为Bean组件,进入Ioc容器,才能切入Bean
public class LogAspects {
    @Pointcut("execution(* cn.cdulm.service.impl.*.*(..))")
    public void pointcut() {
    }

    // 前置通知
    @Before("pointcut()")
    public void before() {
        System.out.println("before - 前置通知");
    }

    // 后置通知
    @After("pointcut()")
    public void after() {
        System.out.println("after - 后置通知");
    }

    // 后置异常通知
    @AfterThrowing("pointcut()")
    public void afterThrowing() {
        System.out.println("afThrow - 后置异常通知");
    }

    // 后置返回通知
    @AfterReturning("pointcut()")
    public void afterReturning() {
        System.out.println("return - 后置返回通知");
    }

    // 环绕通知
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) {
        // 获取方法名
        String methodName = joinPoint.getSignature().getName();
        // 所有的参数
        Object[] args = joinPoint.getArgs();
        Object res = null;
        try {
            System.out.println("Around - 前置通知:" + methodName + " 方法执行,参数:" + Arrays.asList(args));
            res = joinPoint.proceed();
            System.out.println("Around - 后置通知:" + methodName + " 方法执行,参数:" + Arrays.asList(args));
        } catch (Throwable e) {
            System.out.println("Around - 异常通知:" + e);
        } finally {
            System.out.println("Around - 返回通知:" + res);
        }
        return res;
    }
}

execution(* cn.cdulm.service.impl.*.*(..)) 查看切入的包、类和方法:

可以发现切入的是cn.cdulm.service.impl包下所有的类及方法:

 

 只有UserServiceImpl类:

package cn.cdulm.service.impl;

import cn.cdulm.dao.IUserDao;
import cn.cdulm.entity.User;
import cn.cdulm.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements IUserService {
    @Autowired
    IUserDao userDao;

    @Override
    public User select(Integer id) throws Exception {
        System.out.println("查询");
//        throw new RuntimeException("抛异常啦!");
        return userDao.select(id);
    }

    @Override
    public void add(User user) throws Exception {
        System.out.println("添加");
        userDao.add(user);
    }

    @Override
    public void delete(Integer id) throws Exception {
        System.out.println("删除");
        userDao.delete(id);
    }

    @Override
    public void update(User user) throws Exception {
        System.out.println("更改");
        userDao.update(user);
    }
}

 

测试方法:

package cn.cdulm.test;

import cn.cdulm.entity.User;
import cn.cdulm.service.IUserService;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class IocTest {
    @Test
    public void f1() throws Exception {
        ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("classpath:/springIoc.xml");
        IUserService bean = ioc.getBean(IUserService.class);
//        System.out.println(bean.getClass());
        User s = bean.select(112);
        // 没有使用切面结果:class cn.cdulm.service.impl.UserServiceImpl
        /* 使用切面后结果:class com.sun.proxy.$Proxy20 jdk生成的动态代理类
               当类实现了接口会默认由jdk的方式生成代理类
               当类没有实现接口会默认由CGLIB的方式生成代理类
         */
    }
}

 

 输出结果:

Around - 前置通知:select 方法执行,参数:[112]
before - 前置通知
查询
return - 后置返回通知
after - 后置通知
Around - 后置通知:select 方法执行,参数:[112]
Around - 返回通知:cn.cdulm.entity.User@be35cd9

现在将UserServiceImpl中的异常注释打开:

 

 运行结果:

Around - 前置通知:select 方法执行,参数:[112]
before - 前置通知
查询
afThrow - 后置异常通知
after - 后置通知
Around - 异常通知:java.lang.RuntimeException: 抛异常啦!
Around - 返回通知:null

 

由此可以看出@Around环绕通知是五大通知里面功能最全最强的。

 

posted on 2022-06-01 20:39  时间完全不够用啊  阅读(90)  评论(0编辑  收藏  举报