zoukankan      html  css  js  c++  java
  • SSH深度历险(十) AOP原理及相关概念学习+AspectJ注解方式配置spring AOP

        AOP(Aspect Oriented Programming)。是面向切面编程的技术。AOP基于IoC基础。是对OOP的故意补充。


        AOP之所以能得到广泛应用,主要是由于它将应用系统拆分分了2个部分:核心业务逻辑(Core business concerns)及横向的通用逻辑,也就是所谓的切面Crosscutting enterprise concerns。比如,全部大中型应用都要涉及到的持久化管理(Persistent)、事务管理(Transaction Management)、权限管理(Privilege Management)、日志管理(Logging)和调试管理(Debugging)等。

          

        使用AOP技术,能够让开发者仅仅专注核心业务,而通用逻辑则使用AOP技术进行横向切入。由专人去处理这些通用逻辑,会使得任务简单明了,提高开发和调试的效率。

       

        使用AOP,我们要注意关注横切性的功能。即抽象出独立服务。进行模块化使我们曾经习惯性的纵向思维的方法再改变,注意横向思考问题的方式,我们结合如今的系统能够把推断文本框一些了的验证、日志的记录、事务的开启、数据库的开启和关闭等等。都能够抽象出使用切面的形式把这些方法切入进去,我们仅仅须要关心我们的业务逻辑。这样代码简单,间接,开发效率大大提高,更重要的是复用效率大大提高了。 


    基本概念

           要想了解AOP。首先得了解几个重要的基本概念:



    • 切面(Aspect):一个关注点的模块化。这个关注点实现可能另外横切多个对象。比方说事务管理就是J2EE应用中一个非常好的横切关注点样例。切面用Spring的Advisor或拦截器实现。


    • 连接点(Joinpoint):程序运行过程中明白的点,如方法的调用或特定的异常被抛出。
    • 通知(Advice):在特定的连接点,AOP框架运行的动作。

      各种类型的通知包含“around”、“before”和“throws”通知。通知类型将在以下讨论。

      很多AOP框架包含Spring都是以拦截器做通知模型。维护一个“环绕”连接点的拦截器链。


    • 切入点(Pointcut):指定一个通知将被引发的一系列连接点的集合。

      AOP框架必须同意开发人员指定切入点。比如,使用正則表達式。

    • 目标对象(Target Object):包括连接点的对象,也被称作被通知或被代理对象。
    • AOP代理(AOP Proxy):AOP框架创建的对象,包括通知。在Spring中,AOP代理能够是JDK动态代理或CGLIB代理。
    • 编织(Weaving):组装方面来创建一个被通知对象。

      这能够在编译时完毕(比如使用AspectJ编译器),也能够在执行时完毕。Spring和其它纯Java AOP框架一样,在执行时完毕织入。


    各种通知(Advice)类型

        为了符合各种流程处理。通知类型提供了5种,能够对目标方法进行全方位处理:
    • Before advice:在某连接点(JoinPoint)之前运行的通知。但这个通知不能阻止连接点前的运行。
      ApplicationContext中在<aop:aspect>里面使用<aop:before>元素进行声明。
    • After advice:当某连接点退出的时候运行的通知(不论是正常返回还是异常退出)。
      ApplicationContext中在<aop:aspect>里面使用<aop:after>元素进行声明。

    • After returnadvice:在某连接点正常完毕后运行的通知,不包含抛出异常的情况。
      ApplicationContext中在<aop:aspect>里面使用<aop:after-returning>元素进行声明。
    • Around advice:包围一个连接点的通知。类似Web中Servlet规范中的Filter的doFilter方法。能够在方法的调用前后完毕自己定义的行为,也能够选择不运行。


      ApplicationContext中在<aop:aspect>里面使用<aop:around>元素进行声明。

    • Afterthrowing advice:在方法抛出异常退出时运行的通知。


      ApplicationContext中在<aop:aspect>里面使用<aop:after-throwing>元素进行声明。

    本文採用的JDK代理方式


    AspectJ注解方式配置AOP。实例解说


    SecurityHandler,这个通知类能够换成安全性检測、日志管理、事务开启关闭等等。


    <span style="font-family:FangSong_GB2312;font-size:18px;">package com.bjpowernode.spring;
    
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    
    @Aspect
    public class SecurityHandler {
    	
    	
    	/**
    	 * 定义Pointcut。Pointcut的名称为addAddMethod(),此方法没有返回值和參数
    	 * 该方法就是一个标识,不进行调用
    	 */
    	@Pointcut("execution(* add*(..))")
    	private void addAddMethod(){};
    	
    	
    	/**
    	 * 定义Advice,表示我们的Advice应用到哪些Pointcut订阅的Joinpoint上
    	 */
    	//@Before("addAddMethod()")
    	@After("addAddMethod()")
    	private void checkSecurity() {
    		System.out.println("-------checkSecurity-------");
    	}		
    }
    </span>

    UserManager接口



    <span style="font-family:FangSong_GB2312;font-size:18px;">package com.bjpowernode.spring;
    
    public interface UserManager {
    
    	public void addUser(String username, String password);
    	
    	public void delUser(int userId);
    	
    	public String findUserById(int userId);
    	
    	public void modifyUser(int userId, String username, String password);
    }
    </span>

    UserManagerImpl实现



    <span style="font-family:FangSong_GB2312;font-size:18px;">package com.bjpowernode.spring;
    
    public class UserManagerImpl implements UserManager {
    
    	public void addUser(String username, String password) {
    		//checkSecurity();
    		System.out.println("---------UserManagerImpl.add()--------");
    	}
    
    	public void delUser(int userId) {
    		//checkSecurity();
    		System.out.println("---------UserManagerImpl.delUser()--------");
    	}
    
    	public String findUserById(int userId) {
    		//checkSecurity();
    		System.out.println("---------UserManagerImpl.findUserById()--------");
    		return "张三";
    	}
    
    	public void modifyUser(int userId, String username, String password) {
    		//checkSecurity();
    		System.out.println("---------UserManagerImpl.modifyUser()--------");
    	}
    
    //	private void checkSecurity() {
    //		System.out.println("-------checkSecurity-------");
    //	}
    }
    </span>

    application-config.xml中。仅仅须要配置业务逻辑bean和Aspect bean。并启用Aspect注解就可以:


    <span style="font-family:FangSong_GB2312;font-size:18px;"><?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:tx="http://www.springframework.org/schema/tx"
    	     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
               http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
               http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
               
        <!-- 启用AspectJ对Annotation的支持 -->       
    	<aop:aspectj-autoproxy/>           
    	
    	<bean id="userManager" class="com.bjpowernode.spring.UserManagerImpl"/>
    	
    	<bean id="securityHandler" class="com.bjpowernode.spring.SecurityHandler"/>
    </beans>
    </span>

    Clientclient


    <span style="font-family:FangSong_GB2312;font-size:18px;">package com.bjpowernode.spring;
    
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Client {
    
    	public static void main(String[] args) {
    		BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
    		UserManager userManager = (UserManager)factory.getBean("userManager");
    		userManager.addUser("张三", "123");
    	}
    
    }
    </span>



    效果图



    当然我们通过注解的方式能够实现灵活的配置


    <span style="font-family:FangSong_GB2312;font-size:18px;">/**
    	 * 定义Advice。表示我们的Advice应用到哪些Pointcut订阅的Joinpoint上
    	 */
    	@Before("addAddMethod()")
    	//@After("addAddMethod()")
    	private void checkSecurity() {
    		System.out.println("-------checkSecurity-------");
    	}		</span>


    改动后的效果:





    总结

     Annotation

        长处

          保存在 class 文件里,减少维护成本。

              无需工具支持。无需解析。

              编译期就可以验证正确性,查错变得easy。

     

       缺点
            
    若要对配置项进行改动。不得不改动 Java 文件,又一次编译打包应用。


         总的来说,AOP这种优点是我们抽象出公共的方法之后,我们的代码,方法复用性大大提高,实现了可灵活的配置,提高了系统的可靠性。



    接下来


    SSH深度历险(十一) AOP原理及相关概念学习+xml配置实例(对照注解方式的优缺点)

  • 相关阅读:
    对类型化数组的理解
    vue中$bus的传参的坑
    在dva框架和create-react-app创建出来的框架中修饰器语法与按需加载引入antd分别配置
    dva与create-react-app的结合使用
    网络请求之jsonp封装
    js中的超过16位数字相加问题
    dva框架简单描述使用
    后台管理系统之图片上传功能
    剪贴板功能的实现
    前后端登录注册之node剖析与token的使用状态
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/6911272.html
Copyright © 2011-2022 走看看