Spring系列之 二 Spring AOP

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實現事物管理

相關文章
相關標籤/搜索