spring aop
来源:互联网 发布:dnf账号数据出现异常 编辑:程序博客网 时间:2024/05/29 14:10
本人初学aop,刚学时可能会被里面专业的词语(通知,连接点,切入点,切面。。。)搞得晕头转向,其实个人觉得最好的方法还是通过例子学习。
个人理解,AOP简单的说就是将与业务或者主流程无关的代码剥离出来,降低耦合,这样核心代码更加突出,不会穿插很多与业务无关的代码,比如日志模块等。
拿《Spring in Action》里的经典例子来做解释,比如一个演奏家在演奏音乐,在演奏前观众要就坐,关掉手机,演奏高潮时观众要鼓掌。如果我们正常编程序,可能在编写演奏家演奏音乐时(perform())得穿插进观众的程序,即演奏家演奏音乐时,还得忙着指导观众来鼓掌,如下面程序所示:
public void perform(){ audience.takeSeats(); audience.turnOffCellPhones(); System.out.println("Perform"); audience.applaud();}
先看下面演奏者的程序:
public interface Performer {public void perform();}
@Componentpublic class Instrumentalist implements Performer{@Overridepublic void perform() {System.out.println("Perform.");}}
上面定义了演奏者的动作(perform()),这个也是演奏者的主要负责的事情,没有穿插进观众的动作。那么观众应该如何加入进来呢?这时候就用到AOP了,
再贴出一段程序:
@Aspect@Componentpublic class Audience {@Pointcut("execution(* *.perform(..))")public void performance(){};@Before("performance()")public void takeSeats(){System.out.println("Take Seats.");}@Before("performance()")public void turnOffCellPhones(){System.out.println("Turn off CellPhones.");}@AfterReturning("performance()")public void applaud(){System.out.println("Applaud");}public void demandRefund(){System.out.println("demandRefund");}}
这里的观众其实就是一个切面(@Aspect),切面包括了通知(Advice)和切入点(Pointcut),他们组合起来完整的表达了功能,何时何地完成其功能。
切入点定义了“何地”,就是通知要织入的一个或多个连接点,一般是明确的类和方法或者用正则表达式匹配,这里的
@PointCut就相当于切入点,execution(* *.perform(..))中的execution表示执行方法时,第一个*代表任意返回类型,第二个*代表任意类,perform代表perform方法,(..)代表任意参数类型。合起来代表在任意返回类型,任意参数类型的peform()方法中进行切入,即将观众这个切面切入到perform() 方法中。
通知定义了切面的“什么”和“何时使用”,在某个方法被调用之前?之后?之前和之后?这里的@before和@AfterReturning就相当于通知,表示在perform()执行之前和返回之后执行。
这样从代码上,观众与演奏家完全解耦,却可以实现同样的功能。
代码结构如下:
Spring的配置文件如下:
application.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:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"xmlns:task="http://www.springframework.org/schema/task"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsdhttp://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"default-autowire="byName"><context:annotation-config></context:annotation-config><context:component-scan base-package="net.csdn.aop"></context:component-scan><aop:aspectj-autoproxy></aop:aspectj-autoproxy></beans>
测试程序如下:
public class Main {public static void main(String[] args){ApplicationContext ctx = new ClassPathXmlApplicationContext("application.xml");ctx.getBean(Performer.class).perform();}}
这就是一个简单的测试用例,当然,也可以不使用注解,把其中的注解全部去掉,全部在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:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"xmlns:task="http://www.springframework.org/schema/task"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsdhttp://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"default-autowire="byName"> <bean id="instrumentalist" class="net.csdn.aop.Instrumentalist"></bean><bean id="audience" class="net.csdn.aop.Audience"></bean><aop:config><aop:aspect ref="audience"><aop:before method="takeSeats" pointcut="execution(* *.perform(..))"/><aop:before method="turnOffCellPhones" pointcut="execution(* *.perform(..))"/><aop:after-returning method="applaud" pointcut="execution(* *.perform(..))"/></aop:aspect></aop:config></beans>
个人比较喜欢用注解,两种方式可以各选其一~
- AOP、Spring的AOP
- AOP--Spring AOP
- Spring AOP 嵌套AOP
- spring AOP
- Spring AOP
- Spring AOP
- spring aop
- Spring AOP
- spring AOP
- spring aop
- Spring aop
- Spring-AOP
- Spring AOP
- spring aop
- spring aop
- Spring AOP
- Spring AOP
- Spring Aop
- sql 左,右,内连接都可以 一对多。多对一。多对多的
- 良好的目录结构,VS2008
- 最短摘要生成
- 【xcode】提取ipad中的png图片
- NDK build编译的解析
- spring aop
- ubuntu下用命令将源设置为中科大源
- Asp.Net中用户NT AUTHORITY\NETWORK SERVICE 登录失败(SQL2005/2008设置的解决方法)
- 32位的RHEL6如何使用CentOS6的yum源
- World ---Quant 面试题
- xuggle
- CKEditor 3.6入门--在 jsp 中通过自定义标签调用
- AES加密之openssl使用(2)
- hdu1059Dividing 多重背包二进制优化