관점 지향 프로그래밍은 비즈니스와 관련이 없지만 다양한 비즈니스 모듈에서 공동으로 호출해야 하는 로직을 추출하여 관점의 형태로 코드로 잘라내어 결합을 줄일 수 있습니다. 시스템의 코드를 줄이고 중복 코드를 줄입니다.
Spring AOP는 런타임 중 사전 컴파일 및 동적 프록시를 통해 측면 지향 프로그래밍을 구현합니다.
AOP의 최하위 계층은 동적 프록시를 사용하여 요구 사항을 완료하고 추가해야 하는 클래스에 대한 프록시 클래스를 생성합니다. 향상된 기능 프록시 클래스를 생성하는 방법에는 두 가지가 있습니다. 프록시 클래스(즉, 향상이 필요한 클래스)의 경우 If:
인터페이스를 구현하고 생성된 프록시 클래스인 JDK 동적 프록시를 사용합니다.
CGlib 동적 프록시를 사용하면 생성된 프록시 클래스가 프록시 클래스를 통합합니다
연결 지점: 프록시의 메서드( Enhanced) class
진입점: 실제로 개선이 필요한 메소드
Notification: 개선할 로직 코드
사전 알림: 메인 함수 이전에 실행 실행됨
사후 알림 : 테마 기능 실행 후 실행
서라운드 알림 : 메인 기능 실행 전후에 실행
예외 알림 : 다음 경우에 실행 테마 함수 실행 중 예외가 발생했습니다
최종 알림: Subject 함수 실행 성공 여부와 상관없이 함수가 실행됩니다
Aspect: 포인트컷과 애스펙트의 조합, 즉, Enhanced Method와 Enhanced Function이 Aspect를 구성합니다
Notes: C@aspect: 특정 클래스를 컷 서페이스로 지정, 알림 쓰기, 컷 인 포인트
@before: 해당 전면 알림@afterreturning:
후면 알림 해당@Around:
주변 알림에 해당@AfterThrowing:
Exception 알림에 해당@이후: final 최종 알림에 대한 응답@Pointcut :
Execution ([권한 수정 자]를 선언하기위한 포인트 컷 표현식을보다 간결하게 만들 수 있습니다. 반환 유형][클래스 전체 경로].[메서드 이름][매개변수 목록 유형])
실행(* com.xxx.ABC.add()), ABC 클래스의 메소드 강화
인터페이스 인증 구현인터페이스 인증 계정 구성
account: infos: - account: xinchao secret: admin
@Data public class SecretInfo { private String account; private String secret; }
@Configuration @ConfigurationProperties("account") public class SecretConfig { private List<SecretInfo> infos; private Map<String, SecretInfo> map; private Map<String, TokenInfo> tokenMap = new HashMap<>(); public void setInfos(List<SecretInfo> infos) { this.infos = infos; map = infos.stream().collect(Collectors.toMap(SecretInfo::getAccount, Function.identity())); } public synchronized String getToken(String account, String secret) { SecretInfo info = map.get(account); if (info == null) { throw new BusinessException("无效账号"); } if (!StringUtils.equals(info.getSecret(), secret)) { throw new BusinessException("无效密码"); } TokenInfo tokenInfo = tokenMap.get(account); if (tokenInfo != null && tokenInfo.getToken() != null) { return tokenInfo.getToken(); } tokenInfo = new TokenInfo(); String uuid = UUID.randomUUID().toString(); tokenInfo.setToken(uuid); tokenInfo.setCreateDate(LocalDateTime.now()); tokenInfo.setExpireDate(LocalDateTime.now().plusHours(2)); tokenMap.put(account,tokenInfo); return tokenInfo.getToken(); } public boolean checkCaptcha(String captcha) { return tokenMap.values().stream().anyMatch(e->StringUtils.equals(e.getToken(),captcha)); } }
@Data public class TokenInfo { private LocalDateTime createDate; private LocalDateTime expireDate; private String token; public String getToken() { if (LocalDateTime.now().isBefore(expireDate)) { return token; } return null; } public boolean verification(String token) { return Objects.equals(this.token, token); } }
@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface CaptchaIgnoreAop { }
@Slf4j @Aspect @Component @Order(2) public class CaptchaAop { @Value("${spring.profiles.active:dev}") private String env; @Autowired private SecretConfig config; @Pointcut("execution(public * com.herenit.phsswitch.controller.impl..*.*(..))" + "&&@annotation(org.springframework.web.bind.annotation.PostMapping)" + "&&!@annotation(com.herenit.phsswitch.aop.CaptchaIgnoreAop)") public void tokenAop() { } @Around("tokenAop()") public Object doBefore(ProceedingJoinPoint joinPoint) throws Throwable { Object[] args = joinPoint.getArgs(); if (args.length == 0 || !(args[0] instanceof RequestWrapper) || "test,dev".contains(env)) { log.info("当前环境无需校验token"); return joinPoint.proceed(); } String captcha = ((RequestWrapper) joinPoint.getArgs()[0]).getCaptcha(); if (!config.checkCaptcha(captcha)) { throw new BusinessException("captcha无效"); } return joinPoint.proceed(); } }
5. 인터페이스 테스트
@PostMapping("/login") @CaptchaIgnoreAop public ResponseWrapper login(@RequestBody JSONObject userInfo) { String token = config.getToken(userInfo.getString("loginName") , userInfo.getString("password")); JSONObject result = new JSONObject(); result.put("platformAccessToken", token); return ResponseWrapper.success(result); }
public class RequestWrapper<T> implements Serializable { private static final long serialVersionUID = 8988706670118918321L; public RequestWrapper() { super(); } private T args; private String captcha; private String funcode; public T getArgs() { return args; } public void setArgs(T args) { this.args = args; } public String getCaptcha() { return captcha; } public void setCaptcha(String captcha) { this.captcha = captcha; } public String getFuncode() { return funcode; } public void setFuncode(String funcode) { this.funcode = funcode; } }
위 내용은 Spring AOP를 사용하여 SpringBoot에서 인터페이스 인증을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!