AOP基于纯注解开发

目录

前言

一、纯注解开发

二、操作步骤

1.导入依赖

2.创建目标接口,定义抽象方法,并实现目标接口的实现类,重写方法(目标方法)

3.创建通知类,定义通知方法

4.创建Spring核心配置类

5.测试类

6.测试结果

三、注解解释:

四、注意事项:


前言

  使用xml配置AOP的方法,稍微有些许麻烦,在企业开发中,绝大部分使用注解开发的,效率杠杠的。如果需要了解基于xml方式配置AOP,去找的上一篇文章!


提示:以下是本篇文章正文内容,下面案例可供参考

一、纯注解开发

  •  其实注解开发就是剔除掉Spring的配置文件,使用注解的方式去替代在配置文件所做的事情
  • 在xml配置文件,我们需要把通知类、目标类使用<bean>标签创建出来,然后交给Spring的IOC容器管理。然后在配置AOP

二、操作步骤

1.导入依赖

代码如下(示例):

<dependencies>
        <!--Spring上下文核心包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.2.RELEASE</version>
        </dependency>
        <!--AOP的实现包-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.4</version>
        </dependency>
        <!--Spring和单元测试集成-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.1.2.RELEASE</version>
        </dependency>
        <!--单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
 </dependencies>

2.创建目标接口,定义抽象方法,并实现目标接口的实现类,重写方法(目标方法)

代码如下(示例):

/**
 * @Author:Yan
 * @Date 2022/01/21 20:07
 * @Description 目标接口
 **/
public interface Target {
    String getName(String name);
}
/**
 * @Author:Yan
 * @Date 2022/01/21 20:08
 * @Description 目标接口的实现类
 **/
//@Component注解,相当于使用了<bean>,表示创建类的对象并交给IOC容器管理
@Component
public class TargetImpl implements Target {
    @Override
    public String getName(String name) {
        System.out.println("目标方法...."+name);
        return name;
    }
}

3.创建通知类,定义通知方法

代码如下(示例):

/**
 * @Author:Yan
 * @Date 2022/01/21 19:56
 * @Description 3、创建通知类,定义通知方法
 *    1、通知类使用@Aspect表示该类为切面类 并使用@Component注解表示创建该类对象交给Spring管理
 *    2、定义一个方法,使用@Pointcut("切入点表达式")注解  该方法毫无意义
 *    3、方法使用@通知类型("切入点表达式的方法ming()")
 **/
@Aspect     //表示该方类为切面类
@Component
public class MyAdvice {
    //2、定义一个方法,使用@Pointcut("切入点表达式")注解
    @Pointcut("execution(* com.itheima..*.*(..))")
    public void pointcut() {
    }

    //3、方法使用@通知类型
    @Before("pointcut()")
    public void before() {
        System.out.println("前置通知-->打印日志");
    }

    @After("pointcut()")
    public void after() {
        System.out.println("最终通知-->打印日志");
    }

    @AfterReturning("pointcut()")
    public void afterRun() {
        System.out.println("返回后通知-->打印日志");
    }

    @AfterThrowing("pointcut()")
    public void afterThrow() {
        System.out.println("抛出异常后通知-->打印日志");
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        //获取目标方法的参数
        pjp.getArgs()[0] = "李四";
        System.out.println("环绕通知-->打印日志");
        //将设置好的目标方法参数传回去
        Object proceed = pjp.proceed(pjp.getArgs());
        //并返回,如果不返回,那么接收到的返回值为null
        return proceed;
    }
}

4.创建Spring核心配置类

/**
 * @Author:Yan
 * @Date 2022/01/21 20:09
 * @Description 核心配置类
 *  1、使用@Configuration  表示为该类为核配置类
 *  2、使用@ComponentScan("包的路径")  表示为开启注解扫描
 *  3、使用@EnableAspectJAutoProxy  表示开启AOP注解扫描
 **/
@Configuration  //表示该类为Spring核心配置类
@ComponentScan("com.itheima")  //开启注解扫描
@EnableAspectJAutoProxy  //表示开启AOP注解驱动
public class AppConfig {
}

5.测试类

/**
 * @Author:Yan
 * @Date 2022/01/21 20:14
 * @Description 测试纯注解
 **/
@RunWith(SpringJUnit4ClassRunner.class)    //表示该类测试类
@ContextConfiguration(classes = AppConfig.class)
public class textAnno {
    //定义目标类的属性  使用@Autowiredr注解为该属性注入数据
    @Autowired
    private Target target;

    @Test
    public void method() {
        //调用方法
        String name = target.getName("张三");
        System.out.println(name);
    }
}

6.测试结果

环绕通知-->打印日志
前置通知-->打印日志
目标方法....李四
最终通知-->打印日志
返回后通知-->打印日志
李四

三、注解解释:

  •  @Aspect:该注解作用在类上,表示该类是一个切面类。替代xml方式中的<aop:aspect ref="通知类唯一标识">
  •  @Component:该注解作用在类上,用于创建该类的对象并交给IOC容器管理,替代xml方式中的<bean>标签

  • @Pointcut("execution= "):该注解作用于方法上,使用当前方法名作为切入点引用名称,方法毫无意义。execution属性用于定义切入点表达式。替代xml方式中的<aop:pointcut id="" expression="execution(切入点表达式)"/>

  • @Before("切入点方法名()") 、@After("切入点方法名()")、@AfterReturning("切入点方法名()")、@AfterThrowing("切入点方法名()")、@Around("切入点方法名()"):这些注解作用于方法上,表示该方法属于何种通知类型,并指定切入点表达式。

  • @Configuration  该注解作用于类上,表示该类为Spring核心配置类   一般用于配置类上

  • @ComponentScan("com.itheima")  该注解作用于类上,表示开启Spring注解扫描。  一般用于配置类上

  • @EnableAspectJAutoProxy  该注解作用于类上,表示开启AOP注解驱动。一般用于配置类上

  • @RunWith(SpringJUnit4ClassRunner.class)   该注解作用于类上,表示该类测试类。

  • @ContextConfiguration(classes = AppConfig.class)  该注解作用于类上,用于读取Spring配置文件。替代了xml方式需要创建工厂对象

四、注意事项:

  • 如果一个类中的方法被使用AOP增强了  则在SpringIOC容器中管理的是这个类的代理对象  代理对象类型不是实现类类型 但是属于接口类型所以 在使用 AOP之后 获取一个bean对象 通过接口类型获取  不能在通过实现类类型获取了只要类中有一个方法被AOP增强了 则存在Spring IOC容器中的bean对象 就是代理对象 必须使用接口类型获取接收

  • 定义环绕增强时 就需要设置方法参数了,如果不设置 其功能就等价于前置增强  ProceedingJoinPoint就是要进行增强的目标方法

                      不是设置参数时,会执行环绕通知,而不会执行前置通知

                      使用 ProceedingJoinPoint获取方法参数 重新赋值  修改参数  需要将该参数传递给目标方法

                       proceed():调用目标方法执行  如果有参数就在小括号中传递

                      环绕通知可以使用 ProceedingJoinPoint修改目标方法的返回值,那么该环绕通知的方法需要有返回值

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值