AOP (Aspect Oriented Programming)是一項偉大的開闊者,以前OOP的思想一直很流行,可是OOP也有其缺點:針對不少地方都要執行的無關於業務的代碼,很難分離出來,致使不少業務方法中都要加入不少無關業務邏輯的方法,好比監控,,日誌,權限,事務等不少地方都要重複寫的代碼.AOP把這些無關的代碼從業務邏輯中分離出來.畫了個簡單的圖來講明AOP的做用.java
Spring中的AOPspring
Spring中AOP是利用了AspectJ的切點表達式語法來定位PointCut(切點:須要加入),而後定義Advance(加強:須要加入的方法)和其方位(before,after,round,afterThrowing .... ),具體實現就是利用反射和動態代理模式生成代理類.Spring能夠用JDK本身的動態代理(基於接口),CGLIB(基於繼承)來實現動態代理.CGLIB的效率比較高,並且JDK動態代理必需要被代理類繼承了接口.express
選擇使用代理的方式是在 DefaultAopProxyFactory 中的createAopProxy方法判斷的ui
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { Class<?> targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } if (targetClass.isInterface()) { return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } }
意思是若是實現了接口,沒有用 proxy-target-class="true"強制指定使用類繼承的方式的話就會使用JDK代理,若是指定了使用類繼承或者被代理類沒有實現接口就會使用CGlib代理.spa
1.在Spring中使用AOP的XML配置(aspect風格):
代理
<?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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd"> <aop:config proxy-target-class="true"> <aop:aspect id="myAspect" ref="logIntercepter"> <aop:pointcut id="loginPointCut" expression="execution(* com.lubby.service.impl.*.*(..))" /> <aop:before pointcut-ref="loginPointCut" method="startLog"/> <aop:after pointcut-ref="loginPointCut" method="endLog"/> <aop:around pointcut-ref="loginPointCut" method="round" /> </aop:aspect> </aop:config> </beans>
其實就是先配置一個aop指定使用類繼承(cglib)的實現,而後指定須要加強(增長的方法),而後使用aspectJ語法定於切面,而後定義加強的方位.就這麼簡單.日誌
2.在Spring中使用Anotation:code
啓用aspectJ註解,指定使用類代理實現動態代理xml
<aop:aspectj-autoproxy proxy-target-class="true" />
指定加強類,在須要加入的方法上面指定方位以及切面繼承
@Aspect @Component public class LogIntercepter { @Before("execution(* com.lubby.service.impl.*.*(..))") public void startLog(){ System.out.println("starting time:" + new Date()); } @After("execution(* com.lubby.service.impl.*.*(..))") public void endLog(){ System.out.println("ending time:" + new Date()); } @Around("execution(* com.lubby.service.impl.*.*(..))") public Object round(ProceedingJoinPoint pjp) throws Throwable { System.out.println("starting time:" + new Date()); Object object = pjp.proceed(); System.out.println("ending time:" + new Date()); return object; } }
下一章節再說利用Spring AOP實現事物管理