前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >spring框架应用系列三:切面编程(带参数)

spring框架应用系列三:切面编程(带参数)

作者头像
用户7225427
发布2020-09-03 10:18:59
4740
发布2020-09-03 10:18:59
举报
文章被收录于专栏:厚积薄发厚积薄发

切面编程(带参数)

本文系作者原创,转载请注明出处:http://www.cnblogs.com/further-further-further/p/7786715.html

解决问题

1、分离业务监控与业务处理。简单点说,让开发人员更专注业务逻辑开发,类似于打印日志、统计时间、监控等等独立成一个单独的类,在需要的时候,动态的将代码切入到类的指定方法上,使方法拥有更强大的功能;

2、解决代码重复性,降低代码复杂程度;

内容说明

1、通过@Component注解,扫描(Magician)bean并注册到spring容器中时,需在XML配置文件中引入 <context:component-scan base-package="com.spring.example.aspectArgs"/>;

2、明确切面、切点、通知概念,这里切面是Magician,切点是Volunteer的thinkOfSomething方法,通知是Magician中所包含方法,由xml或注解配置,下面会分别给出示例;

3、通过执行Volunteer的thinkOfSomething方法,从而执行Magician中相应的方法,达到通知的效果;

应用实例:截听志愿者内心真实想法

先列出相关接口以及类代码

切面实现接口MindReader(读心者)

package com.spring.example.aspectAspectJArgs;

//读心者
public interface MindReader {
    void interceptThoughts(String thoughts);
    void getConclusion(String thoughts);
}

切点类志愿者实现接口Thinker

package com.spring.example.aspectAspectJArgs;

/**
 * 读心者赋予一个他需要截听内心感应的志愿者
 */
public interface Thinker {
    void thinkOfSomething(String thoughts);
}

志愿者实体类Volunteer

package com.spring.example.aspectAspectJArgs;

import org.springframework.stereotype.Component;

/**
 * Created by weixw on 2017/10/24.
 */
@Component
public class Volunteer implements Thinker {

    private String thoughts;
    @Override
    public void thinkOfSomething(String thoughts) {
        this.thoughts = thoughts;

    }

}

以下有两种方式实现此实例的切面编程:一、通过XML配置文件,二、AspectJ注解方式

其他代码都相同,不同处在spring 的xml配置文件以及切面类文件

一、通过XML配置文件:

切面(读心者)实体类

package com.spring.example.aspectArgs;

/**
 * Created by weixw on 2017/10/24.
 */

import org.springframework.stereotype.Component;

/**
 * 截听志愿者的内心感应和显示他们在想什么
 */
@Component
public class Magician implements MindReader {

    @Override
    public void interceptThoughts(String thoughts) {
        System.out.println("Intercepting volunteer's thoughts :" +thoughts);
    }

    @Override
    public void getConclusion(String thoughts) {
        System.out.println("For your thoughts :" +thoughts);
        System.out.println("I think you are right.");
    }

}

spring 配置文件 aspect-args.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 

http://www.springframework.org/schema/beans/spring-beans.xsd  http://www.springframework.org/schema/aop 

http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context 

http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.spring.example.aspectArgs"/>

    <aop:config>
           <!--通过component-scan自动扫描,@Component注解将Magician注册到spring容器-->
            <aop:aspect ref="magician">
                <aop:pointcut id="thinking" expression="execution(* 

com.spring.example.aspectArgs.Thinker.thinkOfSomething(String))
                             and args(thoughts)"/>
                <aop:before pointcut-ref="thinking" method="interceptThoughts" arg-names="thoughts"/>
                <aop:after pointcut-ref="thinking" method="getConclusion" arg-names="thoughts"/>
            </aop:aspect>
    </aop:config>
</beans>

二 、AspectJ注解方式

切面(读心者)实体类

package com.spring.example.aspectAspectJArgs;

/**
 * Created by weixw on 2017/10/24.
 */

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * 截听志愿者的内心感应和显示他们在想什么
 */
@Component
@Aspect
public class Magician implements MindReader {

    @Pointcut("execution(* com.spring.example.aspectAspectJArgs.Thinker.thinkOfSomething(String)) " +
            "&& args(thoughts)") //定义切点
    public void thinkOfSomething(String thoughts){}
    @Before("thinkOfSomething(thoughts)")
    @Override
    public void interceptThoughts(String thoughts) {
        System.out.println("Intercepting volunteer's thoughts :" +thoughts);
    }
    @AfterReturning("thinkOfSomething(thoughts)")
    @Override
    public void getConclusion(String thoughts) {
        System.out.println("For your thoughts :" +thoughts);
        System.out.println("I think you are right.");
    }

}

spring 配置文件 aspect-aspectJArgs.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 

http://www.springframework.org/schema/beans/spring-beans.xsd  http://www.springframework.org/schema/aop 

http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context 

http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.spring.example.aspectAspectJArgs"/>
    <aop:aspectj-autoproxy/>
   
</beans>

测试代码

注解测试代码如下,配置文件测试代码只需将配置文件名称改成spring/aspect-args.xml即可

package com.spring.example.aspectAspectJArgs;/**
 * Created by weixw on 2017/10/19.
 */

import javafx.application.Application;
import javafx.stage.Stage;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Driver extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        try {

            ApplicationContext ctx = new ClassPathXmlApplicationContext("spring/aspect-aspectJArgs.xml");
            Thinker thinker = (Thinker) ctx.getBean("volunteer");
            thinker.thinkOfSomething("I'm stupid.");

        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

运行结果

总结

上述列出配置文件和注解两种方式都能实现切面编程。但对于自身业务开发,个人觉得注解方式较好,因为在修改某一切面类时不需要多处修改;

本文描述可能有不对或不全之处,欢迎大家吐槽!

不要让懒惰占据你的大脑,不要让妥协拖垮你的人生。青春就是一张票,能不能赶上时代的快车,你的步伐掌握在你的脚下。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-11-05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 切面编程(带参数)
    • 解决问题
      • 内容说明
        • 应用实例:截听志愿者内心真实想法
          • 一、通过XML配置文件:
            • 二 、AspectJ注解方式
              • 测试代码
                • 运行结果
                  • 总结
                  相关产品与服务
                  容器服务
                  腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档