目錄
一、AOP簡介
1.1、定義
wiki:面向切面的編程
個人理解:利用切面思想,將與程序無關的業務和當前程序解耦開,並進行監控或者後續處理等功能。
1.2、AOP五種通知類型
(1)、Before:在目標方法被調用之前做增強處理,@Before只需要指定切入點表達式即可
(2)、AfterReturning:在目標方法正常完成後做增強,@AfterReturning除了指定切入點表達式後,還可以指定一個返回值形參名returning,代表目標方法的返回值
(3)、AfterThrowing:主要用來處理程序中未處理的異常,@AfterThrowing除了指定切入點表達式後,還可以指定一個throwing的返回值形參名,可以通過該形參名
來訪問目標方法中所拋出的異常對象
(4)、After:在目標方法完成之後做增強,無論目標方法時候成功完成。@After可以指定一個切入點表達式
(5)、Around:環繞通知,在目標方法完成前後做增強處理,環繞通知是最重要的通知類型,像事務,日誌等都是環繞通知,注意編程中核心是一個ProceedingJoinPoint
二、Hystrix和AOP的結合
主要利用了aop的Around環繞通知功能。
(1)Hystrix監控
import com.alibaba.fastjson.JSON;
import com.netflix.hystrix.*;
import org.aopalliance.intercept.MethodInvocation;
/**
* Created by JackDing on 18/10/25.
*/
public class HelloWorldCommand extends HystrixCommand<String> {
private final String name;
private MethodInvocation methodInvocation;
public HelloWorldCommand(String name,MethodInvocation methodInvocation) {
super(
Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ServiceGroup"))//命名組
.andCommandKey(HystrixCommandKey.Factory.asKey("servcie1query")) //命名名稱
.andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("service1ThreadPool")) //命令線程池
.andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter()
.withCoreSize(20))//服務線程池數量
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
.withCircuitBreakerErrorThresholdPercentage(60)//熔斷器關閉到打開閾值
.withCircuitBreakerSleepWindowInMilliseconds(3000)//熔斷器打開到關閉的時間窗長度
));
this.name = name;
this.methodInvocation=methodInvocation;
}
@Override
protected String getFallback() {
return "執行異常";
}
@Override
protected String run() throws Exception {
// 依賴邏輯封裝在run()方法中
/* ShopService shopService= (ShopService) ApplicationContextUtils.getBeanByName("shopService");
List<Integer> shopIds=new ArrayList<>();
shopIds.add(5740403);
List<ShopDTO> babySubCardInfoDTO=shopService.findShops(shopIds);*/
Object result=null;
try {
result=methodInvocation.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return JSON.toJSONString(result);
}
}
(2)Around切面點邏輯處理
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/**
* Created by JackDing on 18/10/30.
*/
public class Around implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
System.out.println("準備好了嗎?");
HelloWorldCommand command=new HelloWorldCommand("test",methodInvocation);
Object result= command.queue().get();
System.out.println("已經結束了!");
return result;
}
}
(3)Around切面點需要關注的方法攔截
<bean id="aroundFilter" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<bean class="com.dianping.baby.activity.aop.Around"></bean>
</property>
<property name="patterns">
<list>
<value>.*test.*</value>
</list>
</property>
</bean>
<bean id="test" class="com.dianping.baby.activity.reliability.TestImpl">
<property name="groupName" value="groupTest"></property>
<property name="commandName" value="commandTest"></property>
<property name="threadPoolName" value="threadPoolTest"></property>
<property name="threadPoolSize" value="10"></property>
<property name="breakerErrorThreshold" value="20"></property>
<property name="breakerSleepWindowInMilliseconds" value="3000"></property>
</bean>
(4)切面點配置
<aop:config>
<aop:pointcut expression="execution(* com.dianping.baby.activity.reliability.Test.*())" id="pointcut"/>
<!-- <aop:advisor advice-ref="before" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="after" pointcut-ref="pointcut"/>-->
<aop:advisor advice-ref="around" pointcut-ref="pointcut"/>
</aop:config>