欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring实践之面向切面编程(AOP)

程序员文章站 2022-06-05 13:48:45
...

面向切面编程(AOP)

在运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程(Aspect Oriented Programming)。

实现

这里直接上代码, 具体原理后面写.

依赖

这里会使用@AspectJ来实现Spring AOP. 需要使用maven加载以下依赖.

 <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.9.RELEASE</version>
</dependency>
<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.3.9.RELEASE</version>
</dependency>
<dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.10</version>
</dependency>

代码结构:

Spring实践之面向切面编程(AOP)

代码

Worker.java

这个是需要被AOP的类, AOP可以动态地将代码插入到它的方法. 具体见下面的TimeRecordAspect.java

package spring.aop;

/**
 * @author ixuhangyi
 * @since 2017/7/18.
 */
public interface Worker {
    void work();
}

WorkerImpl.java

Worker类的实现

package spring.aop;

import org.springframework.stereotype.Service;

/**
 * @author ixuhangyi
 * @since 2017/7/18.
 */
@Service
public class WorkerImpl implements Worker {
    public void work() {
        System.out.println("working");
    }
}

TimeRecordAspect.java

package spring.aop;


import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.cache.interceptor.CacheOperationInvoker;
import org.springframework.stereotype.Service;

/**
 * @author ixuhangyi
 * @since 2017/7/18.
 */
 // @Aspect 声明这是一个切面
@Service
@Aspect
public class TimeRecordAspect {
    // 在sprint.aop.WorkerImpl.work()方法中实现面向切面, 在方法调用前/调用后, 插入了记录时间的代码
    // 与@Around类似的有@Before, @After等
    @Around("execution(* spring.aop.WorkerImpl.work(..))")
    public void beforeWork(ProceedingJoinPoint point) throws Throwable {
        System.out.println("method start time:" + System.currentTimeMillis());
        Object object = point.proceed();
        System.out.println("method end time:" + System.currentTimeMillis());
    }
}

App.java

package spring.aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

/**
 * @author ixuhangyi
 * @since 2017/7/18.
 */
@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class App {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(App.class);
        Worker worker = context.getBean(Worker.class);
        worker.work();
    }
}

运行结果

method start time:1500437326224
working
method end time:1500437326224

可以看到在不修改任何Worker.work()代码的情况下, 实现了动态增加代码的功能.