zoukankan      html  css  js  c++  java
  • Spring 入门 AOP

    通过一个小例子演视怎么使用 Spring 现实面向切面编程。

    导入 Spring 所需要的包

    spring-framework-2.5.6 版需要导入以下包:
    1.----- spring.jar
    2.----- commons-logging.jar
    3.----- aspectjrt.jar
    4.----- aspectjweaver.jar
    5.----- cglib-nodep-2.1_3.jar

    spring-framework-3.2.4 版需要导入以下包:
    1.----- spring-core-3.2.4.RELEASE.jar
    2.----- spring-beans-3.2.4.RELEASE.jar
    3.----- spring-context-3.2.4.RELEASE.jar
    4.----- spring-expression-3.2.4.RELEASE.jar
    5.----- commons-logging.jar
    6.----- aspectjweaver.jar
    7.----- aspectjrt.jar
    8.----- aopalliance.jar(spring项目里不提供,要到网上下)

    代码:

    Book.java:

    public class Book {
        private int id;
        private String name;
        //省略get set方法....    
    }

    BookService.java:

    public class BookService {
        public void save(Book book){
            System.out.println("save:"+book.getName());
        }
        
    }

    main方法:

    public static void main(String[] args) {
        ApplicationContext appctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        Book b = (Book)appctx.getBean("book");
        b.setName("j2ee");
        BookService bs = (BookService)appctx.getBean("bookService");
        //调用BookService的save方法。
        bs.save(b);
        ((ClassPathXmlApplicationContext)appctx).close();
    }

    通过使用Spring AOP 在调用BookService的save方法前后各加上一些业务(如记录日志,时间等等)方便起见,这里简单输出两句话。

    使用配置文件配置AOP(Schema)

    添加切面类 Log.java :

    public class Log {
        //在目标方法执行前调用此方法,JoinPoint:封装了目标方法的一些信息(如类名,参数等等)
        public void before(JoinPoint jp){
            
            System.out.println(jp.getSignature().getName()+":开始执行----------");
            // 获取被代理对象
            System.out.println("被代理对象:"+jp.getTarget().getClass());
            // 获取被代理方法
            System.out.println("被代理方法:"+jp.getSignature());
            // 获取方法参数
            System.out.println("方法参数:"+jp.getArgs());
        }
        //在目标方法执行完后调用此方法,Object rn:目标方法的返回值(void为null)
        public void afterreturning(JoinPoint jp,Object rn){
            System.out.println(jp.getSignature().getName()+":执行完毕----------");
            
            System.out.println(rn);
        }
    }

    Spring配置文件:

    <?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"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
    
        <bean id="book" class="com.startspring.Book" />
        <bean id="bookService" class="com.startspring.BookService" />
        <bean id="log" class="com.startspring.aop.Log" />
        
        <aop:config>
            <!-- 指定切入点 -->
            <aop:pointcut id="bookSave" expression="execution(public void com.startspring.BookService.save(com.startspring.Book))" />
            <!-- 指定切面 -->
            <aop:aspect id="aspect" ref="log">
                <!-- 前置通知(增强):指明切入点方法执行前执行 “before”方法-->
                <aop:before method="before" pointcut-ref="bookSave"/>
                <!-- 后置通知(增强):指明切入点方法完成后执行 “afterreturning”方法,参数rn是目标方法的返回值-->
                <aop:after-returning method="afterreturning" pointcut-ref="bookSave" returning="rn"/>
            </aop:aspect>
        </aop:config>
    </beans>

    注:要使用aop:标签要先引入aop命名空间(第4、7、8行)

    使注解配置AOP(Annotation)

    Spring配置文件:

    <?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:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-2.5.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
    
        <context:component-scan base-package="com.startspring" />
        <!-- 要使用aspect的注解,先要在配置文件中添加如下代码:启动自动匹配注解类-->
        <aop:aspectj-autoproxy />
        
    </beans>

    添加切面类 Log.java :

    @Component
    @Aspect  //声明该类为切面类
    public class Log {
        //前置通知(增强):指明切入点方法执行前执行该方法
        //后面参数指定了插入点
        @Before("execution(public void com.startspring.BookService.save(com.startspring.Book))")
        public void before(JoinPoint jp){
            System.out.println(jp.getSignature().getName()+":开始执行----------");
            // 获取被代理对象
            System.out.println("被代理对象:"+jp.getTarget().getClass());
            // 获取被代理方法
            System.out.println("被代理方法:"+jp.getSignature());
            // 获取方法参数
            System.out.println("方法参数:"+jp.getArgs());
        }
        
        //后置通知(增强):指明切入点方法执行完毕执行该方法
        //returning="rn" :声明参数rn是目标方法的返回值(void为null)
        @AfterReturning(returning="rn",value="execution(public void com.startspring.BookService.save(com.startspring.Book))")
        public void afterreturning(JoinPoint jp,Object rn){
            System.out.println(jp.getSignature().getName()+":开始完毕----------");
            System.out.println(rn);
            
        }
    }

    这里Bean的声明也采用了注解,要在Book.java和BookService.java里添加相应的注解。或在配置文件中写<bean>也是可以的。

    通过现实接口配置AOP

    添加切面类 Log.java :

    /*
     * 通过实现 MethodBeforeAdvice 实现前置处理。AfterReturningAdvice:后置处理。
     * 分别重写方法:before,afterReturning
     */
    public class Log implements MethodBeforeAdvice,AfterReturningAdvice{    
        
        //method:表示切入点方法.args:切入点方法的参数.target:目标对象
        public void before(Method method, Object[] args, Object target)throws Throwable {
            System.out.println(method.getName()+":开始执行----------");
            // 获取被代理对象
            System.out.println("被代理对象:"+target);
            // 获取被代理方法
            System.out.println("被代理方法:"+method);
            // 获取方法参数
            System.out.println("方法参数:"+args);
            
        }
        
        //result表示目标方法的返回值
        public void afterReturning(Object result, Method method, Object[] args,Object target) throws Throwable {
            System.out.println(method.getName()+":执行完毕----------");
            
            System.out.println(result);
            
        }
    }

    Spring配置文件:

    <?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"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
    
        <bean id="book" class="com.startspring.Book" />
        <bean id="bookService" class="com.startspring.BookService" />
        <bean id="log" class="com.startspring.aop.Log" />
        
        <aop:config>
            <!-- 指定切入点 -->
            <aop:pointcut id="bookSave" expression="execution(public void com.startspring.BookService.save(com.startspring.Book))" />
            <!-- advice-ref:指定切面   pointcut-ref:指定切入点-->
            <aop:advisor advice-ref="log" pointcut-ref="bookSave"/>
        </aop:config>
    </beans>
  • 相关阅读:
    通过actionlib控制jaco机械臂
    actionlib学习
    配置 jaco机械臂 ros环境
    ubuntu14.04标题栏显示上下网速
    linux下alsa架构音频驱动播放wav格式文件
    ros语音交互(五)移植科大讯飞语音识别到ros
    ubuntu14.04 wifi驱动
    Ubuntu14.04使用apt-fast来加快apt-get下载的教程
    ROS语音交互(四)接入图灵语义理解
    相比传统游戏,区块链游戏的价值在哪里?
  • 原文地址:https://www.cnblogs.com/likailan/p/3457239.html
Copyright © 2011-2022 走看看