Spring_6

Spring学习(18)--- AOP基本概念及特点 出处:http://www.cnblogs.com/JsonShare

Spring官方文档:http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#overview-distribution-zip

    • AOP:Aspect Oriented Programing的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序程序功能的统一维护的一种技术
    • 主要的功能是:日志记录,性能统计,安全控制,事务处理,异常处理... 
    • 注意:切面的是垂直于功能的 
  •  AOP的实现方式:
    1. 预编译   ---  AspectJ
    2. 运行期动态代理(JDK动态代理,CGLib动态代理)    ----  SpringAOP、JbossAOP
  •  AOP几个相关的概念        

            

名称 说明
切面(Aspect) 一个关注点的模块化,这个关注点可能会横切多个对象
连接点(Joinpoint) 程序执行过程中的某个特定的点
通知(Advice) 在切面的某个特定的连接点上执行的动作
切入点(Pointcut) 匹配连接点的断言,在AOP中通知和一个切入点的表达式
引入(Introduction) 再不修改类代码的前提下,为类添加新的方法和属性
目标对象(Target Object) 被一个或多个切面所通知的对象
AOP代理(AOP Proxy) AOP框架创建的对象,用来实现切面契约(aspect contract)(包括通知方法执行等功能)
织入(Weaving) 把切面连接到其他的应用程序类型或者对象上,并创建一个被通知的对象,     分为:编译时织入、类加载时织入、执行时织入
  •  Advice的类型
名称 说明
前置通知(Before advice) 在某个连接点(join point)之前执行的通知,但不能阻止连接点前的执行(除非它抛出异常)
返回后通知(After returning advice) 在某个连接点(join point)正常完成后执行的通知
抛出异常后通知(After throwing advice) 在方法抛出异常退出时执行的通知
后通知(After(finally) advice) 当某个连接点退出的时候执行的通知(无论是正常返回还是异常退出)
环绕通知(Around advice) 包围一个连接点(join point)的通知
  •  Spring框架中AOP的用途
    1. 提供了声明式的企业服务,特别是EJB的替代服务声明
    2. 允许用户定制自己的切面,以完成OOP与AOP的互补使用
  • Spring的AOP实现
    1. 纯java的实现,无特殊的变编译过程,不需要控制类加载器层次
    2. 目前只支持方法执行的连接点(通知Spring Bean 的方法执行)
    3. 不是为了提供最完整的AOP实现(尽管他非常强大);而是侧重于提供一种AOP实现和Spring IOC 容器之间的整合,用于帮助解决企业应用中的常见问题
    4. Spring AOP不会与AspectJ(综合全面的AOP解决方案)竞争,也不会提供综合全面的AOP解决方案
  • 有接口无接口的Spring AOP 实现区别
    1. Spring AOP默认使用标准的javaSE动态代理作为AOP代理,这使得任何接口(或者接口集)都可以被代理
    2. Spring AOP中也可以使用CGLib代理(如果一个业务对象并没有实现一个接口)

 以下转自(我感觉讲的很好,值得读完):http://blog.csdn.net/evankaka/article/details/45242505 

       AOP(Aspect-Oriented Programming,面向切面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。

       而AOP技术则恰恰相反,它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即切面。所谓“切面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP代表的是一个横向的关系,如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向切面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。而剖开的切面,也就是所谓的“切面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。

      使用“横切”技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理。Aop 的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。正如Avanade公司的高级方案构架师Adam Magee所说,AOP的核心思想就是“将应用程序中的商业逻辑同对其提供支持的通用服务进行分离。”

===配置切面 aspect=========================

Spring学习(19)--- Schema-based AOP(基于配置的AOP实现) --- 配置切面aspect

    Spring所有的切面和通知器都必须放在一个<aop:config>内(可以配置包含多个<aop:config>元素),每个<aop:config>包含pointcut,advisor和apsect元素。ps:他们必须按照这个顺序进行声明

  • <aop:pointcut>:用来定义切入点,该切入点可以重用;
  • <aop:advisor>:用来定义只有一个通知和一个切入点的切面;
  • <aop:aspect>:用来定义切面,该切面可以包含多个切入点和通知,而且标签内部的通知和切入点定义是无序的;和advisor的区别就在此,advisor只包含一个通知和一个切入点。
<aop:config> AOP定义开始
       <aop:pointcut/>      切入点定义(0或多个)
       <aop:advisor/>      advisor定义(0或多个)
       <aop:aspect>      切面定义开始(0或多个)
                <aop:pointcut/>            切入点定义(0或多个)
                 <aop:before/>            前置通知(0或多个)
                 <aop:after-returning/>            返回后通知(0或多个)
                 <aop:after-throwing/>            抛出异常后通知(0或多个)
                 <aop:after/>            后通知(0或多个)
                 <aop:around/>            环绕通知(0或多个)
                    <aop:declare-parents/>            引入定义(0或多个)
         <aop:aspect>      切面定义结束
</aop:config> AOP定义结束

    <aop:config>风格的配置大量使用了Spring的自动代理机制.

实现:

     <aop:config>
          <aop:aspect id="myAspect" ref="aBean">
             ...
          </aop:aspect>
     </aop:config>
     
     <bean id="aBean" class="...">
           ...
     </bean>

例子:

新建2个类

package com.aop.schema;
/**
 * 
 * 切面类
 *
 */
public class MyAspect {

}
package com.aop.schema;

/**
 * 
 * 业务类
 *
 */
public class ApsectBiz {

}

 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-4.1.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-4.1.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">
         
     <bean id="myAspect" class="com.aop.schema.MyAspect"></bean>
      
     <bean id="apsectBiz" class="com.aop.schema.ApsectBiz"></bean>
      
     <aop:config>
          <aop:aspect id="myAspectAOP" ref="myAspect">
            
          </aop:aspect>
     </aop:config>
 
</beans>

Spring学习(20)--- Schema-based AOP(基于配置的AOP实现) -- 配置切入点pointcut

pointcut(切断点)表达式:

  • execution(public * *(..))  
  • execution(* set*(..))  
  • execution(* com.xyz.service.AccountService.*(..))  
  • execution(* com.xyz.service..(..))  
  • execution(* com.xyz.service...(..))  
  • within(com.xyz.service.*) (only in Spring AOP)
  • within(com.xyz.service..*) (only in Spring AOP)
  • this(com.xyz.service.AccountService) (only in Spring AOP)
  • ....

     execution用于匹配方法执行的连接点

举几个例子:

  • execution(public * *(..))       切入点为执行所有public方法时 
  • execution(* set*(..))        切入点为执行所有set开始的方法时
  • execution(* com.xyz.service.AccountService.*(..))        切入点为执行AccountService类中所有方法时
  • execution(* com.xyz.service..(..))            切入点为执行com.xyz.service包下的所有方法时
  • execution(* com.xyz.service...(..))            切入点为执行com.xyz.service包及其子包下的所有方法时
  • within(com.xyz.service.*) (only in Spring AOP)
  • within(com.xyz.service..*) (only in Spring AOP)            within 用于匹配制定类型内的执行方法
  • this(com.xyz.service.AccountService) (only in Spring AOP)      this 用于匹配当前AOP代理对象类型的执行方法

 其他

  • target(com.xyz.service.AccountService)  (only in Spring AOP)    target 用于匹配当前目标对象类型的执行方法
  • args(java.io.Serializable)   (only in Spring AOP)        args 用于匹配当前执行的方法传入的参数为指定类型的执行方法

基于注解的匹配

  • @target(org.springframework.transaction.annotation.Transactional)  (only in Spring AOP)
  • @within(org.springframework.transaction.annotation.Transactional)  (only in Spring AOP)
  • @annotation(org.springframework.transaction.annotation.Transactional)  (only in Spring AOP)
  • @args(com.xyz.security.Classified)   (only in Spring AOP)

实现:

1
2
3
4
5
<aop:config>
          <aop:pointcut id="businessService" expression="execution(* com.aop.schema..(..))">
           
          </aop:pointcut>
</aop:config>

例子:

新建两个类

1
2
3
4
5
6
7
8
9
package com.aop.schema;
/**
 *
 * 切面类
 *
 */
public class MyAspect {
 
}
1
2
3
4
5
6
7
8
9
10
package com.aop.schema;
 
/**
 *
 * 业务类
 *
 */
public class ApsectBiz {
 
}

XML配置:配置切入点时,可以使用通配符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?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-4.1.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-4.1.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">
          
     <bean id="myAspect" class="com.aop.schema.MyAspect"></bean>
       
     <bean id="apsectBiz" class="com.aop.schema.ApsectBiz"></bean>
       
     <aop:config>
          <aop:aspect id="myAspectAOP" ref="myAspect">
            <aop:pointcut id="myPointcut" expression="execution(* com.aop.schema.ApsectBiz.*(..))" />
          </aop:aspect>
     </aop:config>
  
</beans>
原文地址:https://www.cnblogs.com/charles999/p/6649671.html