Spring-AOP-春天的故事3

来源:互联网 发布:nba球员生涯数据 编辑:程序博客网 时间:2024/04/29 21:22

简介

AOP(Aspect-Oriented Programming):面向切面编程,AOP的主要编程对象是切面,而切面模块化横切关注点.

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

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

实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。
好处

-每个事物逻辑位于一个位置,代码不分散,便于维护升级
-业务模板更简洁,只包含核心业务代码。

使用场景

名称 解释 Authentication 权限 Caching 缓存 Context passing 内容传递 Error handling 错误处理 Lazy loading 懒加载 Debugging 调试 logging, tracing, profiling and monitoring 记录跟踪 优化 校准 Performance optimization 性能优化 Persistence 持久化 Resource pooling 资源池 Synchronization 同步 Transactions 事务

概念

切面 Aspect:横切关注点被模块化的特殊对象
**通知**Advice:切面必须完成的工作
**目标**Target:被通知的对象
**代理**Proxy:向目标对象 应用通知之后创建的对象
**连接点J**oinpoint:程序执行的某个特定位置
切点*pointcut:每个类都拥有多个连接点,即连接点是程序类中客观存在的事物,AOP通过切点定位到特定的连接点。类比:连接点相当于数据库中的记录,切点相当于查询条件。*指定一个通知将被引发的一系列连接点的集合。AOP框架必须允许开发者指定切入点:例如,使用正则表达式。 Spring定义了Pointcut接口,用来组合MethodMatcher和ClassFilter,可以通过名字很清楚的理解, MethodMatcher是用来检查目标类的方法是否可以被应用此通知,而ClassFilter是用来检查Pointcut是否应该应用到目标类上

入门例子,前置通知

场景:在每次调用add,multiply方法前做某些操作,类似日志记录。

package com.test.aop;public interface Calculation {    int add(int x,int y);    int multiply(int x,int y);}
package com.test.aop;import org.springframework.stereotype.Component;@Componentpublic class CalculationImpl implements Calculation {    @Override    public int add(int x, int y) {        return x+y;    }    @Override    public int multiply(int x, int y) {        return x*y;    }}

切面类

package com.test.aop;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.springframework.stereotype.Component;import java.util.Arrays;import java.util.List;//注解表示切面@Aspect@Componentpublic class LoggingAspect {    //前置通知,匹配相应的方法    @Before("execution(public int com.test.aop.CalculationImpl.*(int, int))")    public void beforeMethod(JoinPoint joinpoint){        String methodName=joinpoint.getSignature().getName();        List<Object> params= Arrays.asList(joinpoint.getArgs());        System.out.println("The method is "+methodName+" params are "+params);    }}

测试运行类Main

package com.test.aop;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {    public static void main(String[] args){        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");        Calculation calculation=applicationContext.getBean(Calculation.class);        int result=calculation.add(3,4);        System.out.println("result="+result);    }}

spring配置文件:applicationContext.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: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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">   <context:component-scan base-package="com.test.aop"></context:component-scan>    <!--使Aspectj起作用-->    <aop:aspectj-autoproxy></aop:aspectj-autoproxy></beans>

运行结果:

The method is add params are [3, 4]
result=7

0 0
原创粉丝点击