Spring的AOP开发简单示例

SpringAOP支持方法级别的增强。
大致有
@Before:方法执行前执行
@After:方法执行后还没有返回时执行
@Around:环绕通知,在Before之前,在After之前。
@AfterReturning:方法返回结果之后执行
@AfterThrowing:返回异常时执行
@ @DeclareParents:给类增加接口
假设 增强service包下的所有方法 :
目录结构 :
在这里插入图片描述
切面类:

package com.fuyouj.aspect;

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

/**
 * @Desc
 * @Author FuYouJ
 * @date 2020/5/30 22:27
 */
@Aspect
@Component
public class ServiceAspect {
    //定义需要切割的地方,下面的表达式的意思是 所有限制类型的  service 包下的所有类的所有方法(任意个数参数)
    @Pointcut(value = "execution(* com.fuyouj.service..*.*(..))")
    public void embed(){}
    //方法执行前执行
    @Before("embed()")
    public void before(JoinPoint joinPoint){
        System.out.println("开始调用"+joinPoint);
    }
    //执行完成还没有返回时执行
    @After("embed()")
    public void after(JoinPoint joinPoint){
        System.out.println("调用完成"+joinPoint);
    }

    /**
     * 通过环绕通知达到检测运行时的目的
     * @param joinPoint
     * @return
     */
    @Around("embed()")
    public Object around(JoinPoint joinPoint){
        long start = System.currentTimeMillis();
        //返回值
        Object returnValue = null;
        System.out.println("开始计时"+joinPoint);
        ProceedingJoinPoint point = (ProceedingJoinPoint) joinPoint;
        System.out.println("环绕完毕");
        try {
            returnValue = point.proceed();
        } catch (Throwable throwable) {
            System.out.println("执行失败,结束计时"+joinPoint);
            throwable.printStackTrace();
        }
        finally {
            long end = System.currentTimeMillis();
            System.out.println("耗时"+(end - start));

        }
        return  returnValue;
    }
//方法返回结果之后执行
    @AfterReturning(pointcut = "embed()",returning = "returnValue")
    public void afterReturning(JoinPoint joinPoint,Object returnValue){
        System.out.println("无论为空还是有值都会返回" + joinPoint + "返回值" + returnValue);
    }
    //返回异常时执行
    @AfterThrowing(pointcut = "embed()",throwing = "exception")
    public void afterThrowing(JoinPoint joinPoint,Exception exception){
        System.out.println(joinPoint+"抛出了异常"+exception.getMessage());
    }
    /**
     * 给类增加实现接口和接口的默认实现类
     */
    @DeclareParents(value = "com.fuyouj.controller..*",defaultImpl = com.fuyouj.aspect.ParentImpl.class)
    public Parent parent;
}

控制器里面调用service的方法

@Controller
public class HelloController {
    @Autowired
    private HelloService helloService;
    public void handleRequest(){
        helloService.sayHello();
        helloService.justWantToThrowException();
    }
}
@Controller
public class HiController {
    @Autowired
    private HiService hiService;
    public void handleRequest(){
        hiService.sayHi();
        System.out.println(hiService.justWantToSayHi());
    }
}

两个service

@Service
public class HelloServiceImpl implements HelloService {
    @Override
    public void sayHello() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Hello everyOne");
    }

    @Override
    public void justWantToThrowException() {
        throw new RuntimeException("抛出一个hello Exception");
    }
}
@Service
public class HiServiceImpl implements HiService {
    @Override
    public void sayHi() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Hi everyOne");
    }

    @Override
    public String justWantToSayHi() {
        return "justWantToSayHi";
    }
}

定义增强控制器的接口

public interface Parent {
    void parentMethod();
}
接口实现类
public class ParentImpl implements Parent {
    @Override
    public void parentMethod() {
        System.out.println("额外增加的方法执行了");
    }
}

不转换接口执行

@Configuration
@ComponentScan("com.fuyouj")
//识别AOP
@EnableAspectJAutoProxy
public class Entrance {
    public static void main(String[] args) {
       ApplicationContext applicationContext =  new AnnotationConfigApplicationContext(Entrance.class);
        HelloController helloController = (HelloController) applicationContext.getBean("helloController");
//        ((Parent)helloController).parentMethod();
        helloController.handleRequest();
        HiController hiController = (HiController) applicationContext.getBean("hiController");
        hiController.handleRequest();
    }
}

执行结果:

开始计时execution(void com.fuyouj.service.HelloService.sayHello())
环绕完毕
开始调用execution(void com.fuyouj.service.HelloService.sayHello())
Hello everyOne
耗时2001
调用完成execution(void com.fuyouj.service.HelloService.sayHello())
无论为空还是有值都会返回execution(void com.fuyouj.service.HelloService.sayHello())返回值null
开始计时execution(void com.fuyouj.service.HelloService.justWantToThrowException())
环绕完毕
开始调用execution(void com.fuyouj.service.HelloService.justWantToThrowException())
执行失败,结束计时execution(void com.fuyouj.service.HelloService.justWantToThrowException())
耗时1
调用完成execution(void com.fuyouj.service.HelloService.justWantToThrowException())
无论为空还是有值都会返回execution(void com.fuyouj.service.HelloService.justWantToThrowException())返回值null
开始计时execution(void com.fuyouj.service.HiService.sayHi())
环绕完毕
开始调用execution(void com.fuyouj.service.HiService.sayHi())
java.lang.RuntimeException: 抛出一个hello Exception
	at com.fuyouj.service.impl.HelloServiceImpl.justWantToThrowException(HelloServiceImpl.java:25)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:56)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88)
	at com.fuyouj.aspect.ServiceAspect.around(ServiceAspect.java:44)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633)
	at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.aspectj.AspectJAfterAdvice.invoke(AspectJAfterAdvice.java:47)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:55)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
	at com.sun.proxy.$Proxy27.justWantToThrowException(Unknown Source)
	at com.fuyouj.controller.HelloController.handleRequest(HelloController.java:18)
	at com.fuyouj.controller.HelloController$$FastClassBySpringCGLIB$$71d20363.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
	at org.springframework.aop.support.DelegatePerTargetObjectIntroductionInterceptor.doProceed(DelegatePerTargetObjectIntroductionInterceptor.java:119)
	at org.springframework.aop.support.DelegatePerTargetObjectIntroductionInterceptor.invoke(DelegatePerTargetObjectIntroductionInterceptor.java:107)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
	at com.fuyouj.controller.HelloController$$EnhancerBySpringCGLIB$$13848a28.handleRequest(<generated>)
	at com.fuyouj.Entrance.main(Entrance.java:47)
Hi everyOne
耗时3001
调用完成execution(void com.fuyouj.service.HiService.sayHi())
无论为空还是有值都会返回execution(void com.fuyouj.service.HiService.sayHi())返回值null
开始计时execution(String com.fuyouj.service.HiService.justWantToSayHi())
环绕完毕
开始调用execution(String com.fuyouj.service.HiService.justWantToSayHi())
耗时0
调用完成execution(String com.fuyouj.service.HiService.justWantToSayHi())
无论为空还是有值都会返回execution(String com.fuyouj.service.HiService.justWantToSayHi())返回值justWantToSayHi
justWantToSayHi

Process finished with exit code 0

只测试给类增加接口

 public static void main(String[] args) {
       ApplicationContext applicationContext =  new AnnotationConfigApplicationContext(Entrance.class);
      
        HelloController helloController = (HelloController) applicationContext.getBean("helloController");
        ((Parent)helloController).parentMethod();
    }

运行
在这里插入图片描述
Spring的对一个地方多个AOP执行顺序如下图:
在这里插入图片描述
满足文章开头说的顺序,其实如果记不住这个图,还有个更好的记忆方式。
想象成同心圆。
在这里插入图片描述
先开始的后结束,后开始的先结束。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单springAOP 的使用示例: 1. 创建一个接口和实现类 ```java public interface HelloService { void sayHello(); } public class HelloServiceImpl implements HelloService { public void sayHello() { System.out.println("Hello, World!"); } } ``` 2. 创建一个切面类 ```java @Aspect @Component public class LoggingAspect { @Before("execution(* com.example.service.*.*(..))") public void logBefore(JoinPoint joinPoint) { System.out.println("Method " + joinPoint.getSignature().getName() + " is about to be executed."); } } ``` 3. 在 Spring 配置文件中配置 AOP ```xml <bean id="helloService" class="com.example.service.impl.HelloServiceImpl"/> <aop:aspectj-autoproxy/> <bean id="loggingAspect" class="com.example.aspect.LoggingAspect"/> ``` 4. 测试 ```java public class Test { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); HelloService helloService = (HelloService) context.getBean("helloService"); helloService.sayHello(); } } ``` 输出结果: ``` Method sayHello is about to be executed. Hello, World! ``` 在这个示例中,我们使用 AOP 实现了在 HelloService 的 sayHello() 方法执行前输出一条日志的功能。具体实现是通过在 LoggingAspect 类中定义一个 logBefore() 方法,并使用 @Before 注解告诉 Spring 在方法执行前执行该方法。在 Spring 配置文件中,我们使用 <aop:aspectj-autoproxy/> 开启了 AOP 功能,并将 LoggingAspect 类作为一个 Bean 配置了进去。最后,在测试代码中,我们通过 ApplicationContext 获取到 HelloService 的实例,并调用其 sayHello() 方法,触发 AOP 在方法执行前输出日志的功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值