当前位置: 代码网 > it编程>编程语言>Java > SpringBoot集成AOP的代码示例

SpringBoot集成AOP的代码示例

2024年09月08日 Java 我要评论
1.什么是aop?aop(aspect oriented programming,面向切面编程)是一种编程范式,它旨在将横切关注点(cross-cutting concerns)从应用程序的业务逻辑中

1.什么是aop?

aop(aspect oriented programming,面向切面编程)是一种编程范式,它旨在将横切关注点(cross-cutting concerns)从应用程序的业务逻辑中分离出来。横切关注点是那些在多个模块中重复出现的功能,如日志记录、性能监控、事务管理、安全控制等。aop允许开发者将这些关注点模块化,并在不影响应用程序主要功能的情况下,将它们编织到应用程序的各个点上。

aop的关键概念

  • 切面(aspect):封装了横切关注点的模块。它描述了要执行的附加行为以及该行为应该被应用到哪些连接点上。
  • 连接点(joinpoint):程序执行过程中的某个点,如方法调用或异常抛出。
  • 通知(advice):切面在特定的连接点上执行的动作,如“before”、“after”、“around”等。
  • 切入点(pointcut):匹配连接点的表达式,定义了切面的哪个部分会被应用到哪些连接点上。
  • 目标对象(target object):被一个或多个切面所通知的对象。
  • 代理(proxy):由aop框架创建的对象,用来拦截目标对象上的方法调用。

aop的实现方式

aop可以通过以下几种方式实现:

  • 基于代理的aop:
    • jdk动态代理:适用于实现接口的情况,利用反射机制生成代理类。
    • cglib:使用字节码技术生成子类,适用于未实现接口的情况。
  • 基于字节码操作的aop:
    • aspectj:在编译期或运行期通过修改字节码来实现切面的编织,可以更细粒度地控制切面的织入。
  • 声明式aop:
    • spring aop:使用xml配置或注解(如@aspect@before@after@around等)来定义切面和切入点,然后在运行时通过动态代理实现切面的编织。

实现aop的关键技术

  • 动态代理:在运行时动态创建代理对象,代理对象在调用目标方法前后可以执行额外的操作。
  • 字节码操作库:如asm、bytebuddy等,用于生成或修改字节码,实现在类的加载之前或运行时修改类的行为。
  • 元数据驱动:使用注解或xml配置来定义切面、切入点和通知,便于配置和管理aop的规则。

aop的主要优点是能够减少业务逻辑中的重复代码,提高代码的模块化程度,使得关注点更加集中,同时也提高了代码的可维护性和可读性。在实际应用中,aop经常被用于企业级应用开发,如在spring框架中广泛使用。

2.代码工程

实验目标

采用@aspect注解来实现aop

pom.xml

<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/pom/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
         xsi:schemalocation="http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactid>springboot-demo</artifactid>
        <groupid>com.et</groupid>
        <version>1.0-snapshot</version>
    </parent>
    <modelversion>4.0.0</modelversion>

    <artifactid>aspect</artifactid>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-web</artifactid>
        </dependency>

        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-autoconfigure</artifactid>
        </dependency>
        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-test</artifactid>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupid>org.projectlombok</groupid>
            <artifactid>lombok</artifactid>
        </dependency>
        <dependency>
            <groupid>org.aspectj</groupid>
            <artifactid>aspectjweaver</artifactid>
        </dependency>
       
    </dependencies>
</project>

controller

package com.et.aspect.controller;

import com.et.aspect.service.testservice;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.restcontroller;

import java.util.hashmap;
import java.util.map;

@restcontroller
public class helloworldcontroller {
    @autowired
    testservice testservice;


    @requestmapping("/hello")
    public map<string, object> showhelloworld(){
        map<string, object> map = new hashmap<>();
        string str=  testservice.sayhello("liming");
        map.put("msg",str);
        return map;
    }
}

service

package com.et.aspect.service;

public interface testservice {
    public string sayhello(string name) ;
}

package com.et.aspect.service.impl;

import com.et.aspect.service.testservice;
import lombok.extern.slf4j.slf4j;
import org.springframework.stereotype.service;

/**
 * @author liuhaihua
 * @version 1.0
 * @classname testserviceimpl
 * @description todo
 * @date 2024/09/05/ 9:21
 */
@service
@slf4j
public class testserviceimpl implements testservice {
    @override
    public string sayhello(string name) {
        string  sss="hello,"+name;
        log.info(sss);
        return sss;
    }
}

aspect

  • @aspect:作用是把当前类标识为一个切面供容器读取

  • @pointcut:定义切入点,pointcut是植入advice的触发条件。 每个pointcut的定义包括2部分,一是表达式,二是方法签名。方法签名必须是 public及void型。 可以将pointcut中的方法看作是一个被advice引用的助记符,因为表达式不直观,因此我们可以通过方法签名的方式为 此表达式命名。 因此pointcut中的方法只需要方法签名,而不需要在方法体内编写实际代码。

  • @around:环绕增强,相当于methodinterceptor(方法拦截器)

  • @afterreturning:后置增强,相当于afterreturningadvice,方法正常退出时执行

  • @before:标识一个前置增强方法,相当于beforeadvice的功能,相似功能的还有

  • @afterthrowing:异常抛出增强,相当于throwsadvice(异常通知)

  • @after: final增强,不管是抛出异常或者正常退出都会执行

@pointcut("execution(* com.et.aspect.service..*.*(..))")
public void aoppoint() {

}

@before("aoppoint()")
public void dobefore(joinpoint point) throws throwable {
    log.info("before ....");
}
@after("aoppoint()")
public void doafter(joinpoint point) throws throwable {
    log.info("after ....");
}

以上只是一些关键代码,所有代码请参见下面代码仓库

代码仓库

3.测试

  • 启动spring boot应用程序

  • 访问http://127.0.0.1:8088/hello

  • 查看日志如下

    2024-09-05 21:52:12.926 info 51009 --- [nio-8088-exec-1] com.et.aspect.aspect.taskaspect : before .... 2024-09-05 21:52:12.939 info 51009 --- [nio-8088-exec-1] c.e.aspect.service.impl.testserviceimpl : hello,liming 2024-09-05 21:52:12.939 info 51009 --- [nio-8088-exec-1] com.et.aspect.aspect.taskaspect : after ....

以上就是spring boot集成aop的代码示例的详细内容,更多关于spring boot集成aop的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com