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的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。
好处:
-每个事物逻辑位于一个位置,代码不分散,便于维护升级
-业务模板更简洁,只包含核心业务代码。
使用场景
概念
切面 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
- Spring-AOP-春天的故事3
- Spring-AOP-春天的故事4
- Spring-春天的故事1
- spring-春天的故事2
- Spring-JdbcTemplate-春天的故事5
- 春天的故事
- 春天的故事
- 春天的故事-Spring Security3十五日研究
- 发生在春天的故事
- Spring程序员的春天
- spring带来的春天
- 秋天里的春天-spring笔记(三):AOP in Spring
- AOP、Spring的AOP
- 我的春天——spring
- Spring 2.0冬天里的春天特性
- Spring 2.0寒冬里的“春天”特性
- Spring之开源框架的春天
- Spring系列之J2EE开发的春天
- [HTML/CSS]布局学习笔记-CSS网页平滑移动
- 素材采集 良心题解
- HTML学习小记3
- 自定义View 放在Dialog后点击事件无效
- Eclipse在异常关闭后,启动闪退的解决办法
- Spring-AOP-春天的故事3
- Andriod系统中关于BroadcastReceiver的说法正确的是?
- 万物皆对象,对象皆有类——另一种方式理解Object类,Class类
- Linux环境下Mysql的安装及简单使用
- [1]ruby&ruby on rails入门笔记---解决Ruby install bundler SSL证书的问题
- jquery下载文件到本地
- Codeforces Round #251 (Div. 2)-D. Devu and his Brother
- android:ListView优化
- python property的使用