1. 程式人生 > >spring aop的幾種配置方式

spring aop的幾種配置方式

一 通過@Aspect註解實現aop

service層方法

public interface EventInfoService{
    public int getTEventInfoByCount();
}
@Service("tEventInfoService")
public class EventInfoServiceImpl implements EventInfoService{
    public int getTEventInfoByCount(){
        return 10000;
    }
}

切面類:

@Aspect
public class MyAspect {
    
    //前置通知
    @Before("execution(* com.wutongyu.service.impl.EventInfoServiceImpl.getTEventInfoByCount(..))")
    public void before(){
        System.out.println("前置通知....");
    }
    
    //後置通知
    //returnVal,切點方法執行後的返回值
    @AfterReturning(value="execution(* com.wutongyu.service.impl.EventInfoServiceImpl.getTEventInfoByCount(..))",returning = "returnVal")
    public void AfterReturning(Object returnVal){
        System.out.println("後置通知....返回值為:"+returnVal);
    }
    
    //環繞通知
    //joinPoint 可用於執行切點的類
    @Around("execution(* com.wutongyu.service.impl.EventInfoServiceImpl.getTEventInfoByCount(..))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("環繞通知前....");
        Object obj= (Object) joinPoint.proceed();
        System.out.println("環繞通知後....");
        return obj;
    }
    
    //丟擲通知
    @AfterThrowing(value="execution(* com.wutongyu.service.impl.EventInfoServiceImpl.getTEventInfoByCount(..))",throwing = "e")
    public void afterThrowable(Throwable e){
        System.out.println("出現異常:"+e.getMessage());
    }
    
    //無論什麼情況下,方法執行完都會執行的方法
    @After(value="execution(* com.wutongyu.service.impl.EventInfoServiceImpl.getTEventInfoByCount(..))")
    public void after(){
        System.out.println("最終通知....");
    }
}

spring-test.xml配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.0.xsd"
        default-lazy-init="true">
    <!-- 引入屬性檔案 -->
    <context:annotation-config />
    <!-- 自動掃描(自動注入) -->
    <context:component-scan base-package="com.wutongyu" />
    <aop:aspectj-autoproxy />
    <bean id="myAspect" class="com.wutongyu.service.impl.MyAspect"></bean>
</beans>

測試類:

public class MyTestMain {
    private static final Logger log = LoggerFactory.getLogger( MyTestMain.class );
    private static EventInfoService eventInfoService;
    public static void main(String[] args) {
        //spring初始化beans
        ApplicationContext context = new ClassPathXmlApplicationContext( "classpath:spring-test.xml" );
        eventInfoService=(EventInfoService)context.getBean("tEventInfoService");
        int count = eventInfoService.getTEventInfoByCount();
    }
}

執行結果如下:

環繞通知前....
前置通知....
環繞通知後....
最終通知....
後置通知....10000

 

二 通過@Pointcut註解自定義註解@Retention實現aop

自定義註解:

@Retention(RetentionPolicy.RUNTIME)
public @interface OperationType {
    public String value();
}

宣告切面類和方法:

@Aspect
public class MyPointCutAspect {
    //註解其它的service
    @Autowired(required = false)
    private SysOperationLogService sysOperationLogService;
    //配置掃描的包 正則資訊
    @Pointcut("execution(* com.wutongyu..*(..))")  
    public void allMethodServiceCall(){}
​
    @Around(value="(allMethodServiceCall()) && @annotation(operationType)")
    public void operationServiceCallCalls( ProceedingJoinPoint joinPoint, OperationType operationType){
        //獲取操作方法上的註解資訊
        String operationMethod = "";
        if( joinPoint.getSignature() != null ) {
            operationMethod = operationType.value() == null ? operationMethod : operationType.value();
        }
        Object result = null;
        try {
            result = joinPoint.proceed();
            if(result != null){
            if(result.toString().contains( "1" )||result.toString().equals( "true" ) ){
                result="操作成功";
            }else {
                result="操作失敗";
            }
        }
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        String operationInfo = "使用者進行了[" + operationMethod + "]" + "操作,"+result;
        //操作日誌入庫
    }
}

spring-test.xml配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.0.xsd"
        default-lazy-init="true">
​
    <!-- 自動掃描(自動注入) -->
    <context:component-scan base-package="com.wutongyu" />
    <aop:aspectj-autoproxy />
    <bean id="myPointCutAspect" class="com.wutongyu.service.MyPointCutAspect"></bean>
</beans>

service層方法

public interface EventInfoService{
    public int deleteTEventInfo(String uuid);
    public int batchDelTEventInfos(List<String> uuidList);
}
public interface AlarmInfoService{
    public int deleteAlarmInfo(String uuid);
}
@Service("tEventInfoService")
public class EventInfoServiceImpl implements EventInfoService{
    @OperationType(value = "刪除事件")
    public int deleteTEventInfo(String uuid){
        return tventInfodao.deleteTEventInfo(uuid);
    }
    @OperationType(value = "批量刪除事件")
    public int batchDelTEventInfos(List<String> uuidList){
        return tEventInfodao.batchDelTEventInfos(uuidList);
    }
}
@Service("alarmInfoService")
public class AlarmInfoServiceImpl implements AlarmInfoService{
    @OperationType(value = "刪除告警")
    public int deleteTEventInfo(String uuid){
        return tventInfodao.deleteTEventInfo(uuid);
    }
}