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


                                          切面编程(带参数)                                                   

                                                                  本文系作者原创,转载请注明出处: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>
    View Code

    二 、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();
            }
        }
    }
    View Code

    运行结果

    总结

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

     

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

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

  • 相关阅读:
    Servlet-获取页面的元素的值的方式以及区别
    Http请求-get和post的区别
    Servlet-xml配置简介以及url-pattern简介
    javaweb目录结构简介
    Servlet-生命周期简介
    tomcat-四种运行模式和三种部署模式(优化)
    命名空间System.IO
    Dictionary 字典
    导出-以虚拟表的形式获取数据源
    导入excel-uploadify+npoi
  • 原文地址:https://www.cnblogs.com/further-further-further/p/7786715.html
Copyright © 2020-2023  润新知