springboot+自定義注解實現靈活的切面配置


  利用aop我們可以實現業務代碼與系統級服務例如日志記錄、事務及安全相關業務的解耦,使我們的業務代碼更加干凈整潔。

  最近在做數據權限方面的東西,考慮使用切面對用戶訪問進行攔截,進而確認用戶是否對當前數據有訪問權限,而我們的項目是springboot項目,所以花時間研究了下springboot下切面的實現。

  1、首先加入相關maven依賴:

  

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>            

  2、編寫控制器

  

@RestController

public class HelloController {

    @RequestMapping("/add1")  
    public String addData1(String deviceId) {
        return "success";
    }

    @RequestMapping("/add2")  
    public String addData2(String deviceId) {
        return "success";
    }
    @RequestMapping("/add3")  
    public String addData3(String deviceId) {
        return "success";
    }
    
}

  3、配置切面

  

@Aspect
@Component
public class TestAspect {
	@Pointcut("execution(public * com.example.demo.controller.HelloController.add*(..))")
    public void addAdvice(){}	
	@Around("addAdvice()")
	public Object Interceptor(ProceedingJoinPoint pjp){ 
		Object result = null;  
        Object[] args = pjp.getArgs();
        if(args != null && args.length >0) {
        	String deviceId = (String) args[0];
        	 if(!"03".equals(deviceId)) {
        		 return "no anthorization";
        	 }
        }      
        try {
			result =pjp.proceed();
		} catch (Throwable e) {
			e.printStackTrace();
		}   
        return result;
	}
}

  這樣下來我們就實現了一個簡單切面,在切面中實現自己的數據安全認證,此處只做一個簡單判斷,測試如下:

  

  

  4、但是這樣的切面不夠靈活,所以我們添加一個自定義注解

  

@Documented  
@Retention(RetentionPolicy.RUNTIME)  
@Target(ElementType.METHOD)  
public @interface MyAnnotation {
	
}

  5、修改切面類

  

@Aspect
@Component
public class TestAspect {
	@Pointcut("execution(public * com.example.demo.controller.HelloController.add*(..)) && @annotation(com.example.demo.controller.MyAnnotation)" )
    public void addAdvice(){}	
	@Around("addAdvice()")
	public Object Interceptor(ProceedingJoinPoint pjp){ 
		Object result = null;  
        Object[] args = pjp.getArgs();
        if(args != null && args.length >0) {
        	String deviceId = (String) args[0];
        	 if(!"03".equals(deviceId)) {
        		 return "no anthorization";
        	 }
        }      
        try {
			result =pjp.proceed();
		} catch (Throwable e) {
			e.printStackTrace();
		}   
        return result;
	}
}

  6、修改控制器,給需要切面的方法上加上注解

  

@RestController

public class HelloController {

	@MyAnnotation
    @RequestMapping("/add1")  
    public String addData1(String deviceId) {
    	return "success";
    }

    @RequestMapping("/add2")  
    public String addData2(String deviceId) {
    	return "success";
    }
    @RequestMapping("/add3")  
    public String addData3(String deviceId) {
    	return "success";
    }
    
}

  通過自定義注解,我們可以靈活的添加切面,在需要使用切面的方法上添加注解,測試如下:

  

  

  

  實際開發中我們可以將"execution(public * com.example.demo.controller.HelloController.add*(..)) && @annotation(com.example.demo.controller.MyAnnotation)"改為"execution(public * com.example.demo.controller.*.*(..)) && @annotation(com.example.demo.controller.MyAnnotation)",這樣在controller包下,只有我們加上@MyAnnotation注解的方法切面方法才會起作用。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM