java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > springAop注解

springAop实现讲解(看这篇够了)

作者:screamn

AOP面向切面编程是一种编程范式,它通过将通用的横切关注点(如日志、事务、权限控制等)与业务逻辑分离,使得代码更加清晰、简洁、易于维护,这篇文章主要介绍了springAop实现讲解(看这篇够了),需要的朋友可以参考下

依赖准备

spring-context: 包含Spring的核心功能和上下文支持。spring-aop: 提供了面向切面编程的支持。

什么是代理?

二十三种设计模式中的一种,属于结构型模式。它的作用就是通过提供一个代理类,让我们在调用目标方法的时候,不再是直接对目标方法进行调用,而是通过代理类间接调用。让不属于目标方法核心逻辑的代码从目标方法中剥离出来——解耦。调用目标方法时先调用代理对象的方法,减少对目标方法的调用和打扰,同时让附加功能能够集中在一起也有利于统一维护。

在这里插入图片描述

举例:

杨超越是一个明星,她会唱歌和跳舞,她现在想要举办一场演唱会,那么需要场地的租用和场地搭建这个环境的准备,已经后续的拆除。此时对于这个演唱会核心的内容就是明星杨超越唱歌,跳舞,那么非核心的内容就是场地的搭建,拆除,租用等等,这时候对杨超越来说,我只会唱歌跳舞,这方面的我不会,所以此时就可以让他的经纪人去找负责对应业务的职员搭建和准备演唱会。那么这个经纪人就属于代理。核心业务是跳舞唱歌,非核心业务就是演唱会的相关筹办。 当我们需要对核心代码增加非核心业务的逻辑时可以采用代理的技术。

代理分类

静态代理

静态代理是在编译时期就已经确定的代理方式,在静态代理中,需要手动创建一个代理类,该代理类与被代理类实现相同的接口,并持有一个对被代理对象的引用。通过在代理类中调用被代理对象的方法前后加入自定义的逻辑,实现对目标对象方法的增强或控制。

动态代理

动态代理是在运行时期根据被代理对象生成代理类的方式。在动态代理中,不需要手动创建代理类,而是通过使用Java的反射机制,在运行时动态地创建代理类和代理对象。动态代理可以代理任何实现了接口的类,它通过一组接口来描述被代理类的行为,并提供了一个InvocationHandler接口的实现类来处理代理对象的所有方法调用。在方法被调用时,代理对象会将方法的调用转发给InvocationHandler的invoke()方法,并可以在此方法中添加额外的逻辑。

实现方式(动态代理)

AOP 面向切面编程

它允许开发人员分离横切关注点(cross-cutting concerns)和核心业务逻辑。横切关注点是那些存在于应用程序中多个模块中的功能,例如日志记录、性能统计、安全性和事务管理等。通过 AOP,这些横切关注点可以被模块化地定义,并且可以被动态地应用到整个应用程序中。也就是说将核心代码和非核心代码分割开。

使用场景

Aop名词介绍

SpringAop实现(注解的方式)

接口内容:

package com.ssmLearn;
/**
 *       + - * / 运算的标准接口!
 */
public interface Calculator {
    int add(int i, int j);
    int sub(int i, int j);
    int mul(int i, int j);
    int div(int i, int j);
}

实现类

package com.ssmLearn;
import org.springframework.stereotype.Component;
/**
 * 实现计算接口,单纯添加 + - * / 实现! 掺杂其他功能!
 */
//最后必须放到ioc
@Component
public class CalculatorPureImpl implements Calculator {
    @Override
    public int add(int i, int j) {
        int result = i + j;
        return result;
    }
    @Override
    public int sub(int i, int j) {
        int result = i - j;
        return result;
    }
    @Override
    public int mul(int i, int j) {
        int result = i * j;
        return result;
    }
    @Override
    public int div(int i, int j) {
        int result = i / j;
        return result;
    }
}

需要实现的内容

实现代码

package com.ssmLearn.Aop;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
//使用注解配置插入的代理目标
@Aspect
@Component
public class AchiveAop {
    @Before("execution(* com.ssmLearn.CalculatorPureImpl.*(..))")
    public void start(){
        System.out.println("这是初始化方法");
    }
    @After("execution(* com.ssmLearn.CalculatorPureImpl.*(..)))")
    public void end(){
        System.out.println("这是结束方法");
    }
    @AfterThrowing(value = "execution(public int com.ssmLearn.CalculatorPureImpl.*(..))")
    public void catchExection(){
        System.out.println("出现异常");
    }
}

代码编写

配置类

package com.ssmLearn.config;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@ComponentScan(basePackages = "com.ssmLearn")
//这个是配置的 aspect代理启动入口
@EnableAspectJAutoProxy
public class javaConfig{
}

代码实现

测试类的书写

import com.ssmLearn.Calculator;
import com.ssmLearn.config.javaConfig;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
//@SpringJUnitConfig(locations = "classpath:spring-aop.xml")
@SpringJUnitConfig(value = {javaConfig.class})
class AopTest {
    @Autowired
    private Calculator calculator;
    @Test
    public void testCalculator(){
        int res = calculator.add(1,0);
        System.out.println("res = " + res);
    }
    @Test
    public void test(){
//        使用配置类 就可以直接使用这个ioc容器 直接使用后AnnotationConfigApplicationContext
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(javaConfig.class);
        Calculator bean = applicationContext.getBean(Calculator.class);
        int res = bean.add(1,2);
        System.out.println("res = " + res);
    }
}

代码实现

到此这篇关于springAop讲解的文章就介绍到这了,更多相关springAop讲解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文